Tôi đang làm việc với một điều kiện khá đơn giản: tình huống mà tôi có thể làm cho tham số class_name/external_key hoạt động theo một hướng nhưng không phải là thông số khác. Có lẽ bạn có thể giúp tôi. (p.s. Tôi đang sử dụng Rails 4 nếu điều đó tạo ra sự khác biệt):has_many: thông qua với class_name và foreign_key
Tiếng Anh: Người dùng quản lý nhiều Danh sách thông qua Trình quản lý danh sách và Danh sách được quản lý bởi nhiều Người dùng thông qua Trình quản lý danh sách. Danh sách quản lý có một số lĩnh vực dữ liệu, không Gecman cho câu hỏi này, vì vậy tôi sửa chúng ra trong đoạn code dưới đây
Đây là phần đơn giản mà hoạt động:
class User < ActiveRecord::Base
has_many :listing_managers
has_many :listings, through: :listing_managers
end
class Listing < ActiveRecord::Base
has_many :listing_managers
has_many :managers, through: :listing_managers, class_name: "User", foreign_key: "manager_id"
end
class ListingManager < ActiveRecord::Base
belongs_to :listing
belongs_to :manager, class_name:"User"
attr_accessible :listing_id, :manager_id
end
như bạn có thể đoán từ phía trên bảng vẻ ListingManager như:
create_table "listing_managers", force: true do |t|
t.integer "listing_id"
t.integer "manager_id"
end
nên chỉ không đơn giản ở đây là sử dụng ListingManager manager_id
hơn user_id
Dù sao, các công trình trên. Tôi có thể gọi số user.listings
để có được các Danh sách được liên kết với người dùng và tôi có thể gọi số listing.managers
để yêu cầu người quản lý liên kết với danh sách.
Tuy nhiên (và đây là câu hỏi), tôi quyết định đó không phải là khủng khiếp có ý nghĩa để nói user.listings
kể từ khi một người sử dụng cũng có thể "sở hữu" hơn là "quản lý" danh sách, những gì tôi thực sự muốn là user.managed_listings
vì vậy tôi chỉnh user.rb
thay đổi has_many: danh sách, thông qua:: listing_managers để has_many: managed_listings, thông qua:: listing_managers, class_name: "Liệt kê", foreign_key: "listing_id"
Đây là một loại suy chính xác để mã trong listing.rb
trên, vì vậy tôi nghĩ rằng điều này sẽ làm việc ngay lập tức. Thay vì kiểm tra rspec tôi điều này bằng cách nói barfs ActiveRecord::HasManyThroughSourceAssociationNotFoundError: Could not find the source association(s) :managed_listing or :managed_listings in model ListingManager. Try 'has_many :managed_listings, :through => :listing_managers, :source => <name>'. Is it one of :listing or :manager?
kiểm tra phúc:
it "manages many managed_listings" do
user = FactoryGirl.build(:user)
l1 = FactoryGirl.build(:listing)
l2 = FactoryGirl.build(:listing)
user.managed_listings << l1
user.managed_listings << l2
expect(@user.managed_listings.size).to eq 2
end
Bây giờ, tôi bị thuyết phục tôi không biết gì. Có, tôi đoán tôi có thể làm một bí danh, nhưng tôi lo lắng rằng cùng một kỹ thuật được sử dụng trong listing.rb
dường như không hoạt động trong user.rb
. Bạn có thể giúp giải thích?
CẬP NHẬT: Tôi đã cập nhật mã để phản ánh @gregates đề xuất, nhưng tôi vẫn gặp sự cố: Tôi đã viết một kiểm tra bổ sung không thành công (và được xác nhận bằng "tay" trong bảng điều khiển Rails). Khi một người viết bài kiểm tra như thế này:
it "manages many managed_listings" do
l1 = FactoryGirl.create(:listing)
@user = User.last
ListingManager.destroy_all
@before_count = ListingManager.count
expect( @before_count).to eq 0
lm = FactoryGirl.create(:listing_manager, manager_id: @user.id, listing_id: l1.id)
expect(@user.managed_listings.count).to eq 1
end
Ở trên không thành công. Đường ray tạo lỗi PG::UndefinedColumn: ERROR: column listing_managers.user_id does not exist
(Cần tìm kiếm 'listing_managers.manager_id'). Vì vậy, tôi nghĩ rằng vẫn còn một lỗi về phía người dùng của hiệp hội. Trong số của user.rb
, Người dùng biết cách sử dụng manager_id
để truy cập vào (các) Danh sách của nó như thế nào?
thú vị ... và tôi đã thử 'nguồn:" Danh sách "" nhưng điều đó không hiệu quả. Vì vậy, biểu tượng là cách duy nhất để thiết lập nó. – user2669055
Tôi sẽ đánh dấu điều này là đã trả lời (và cảm ơn vì tốc độ!) Mặc dù tôi vẫn còn hơi mờ về vấn đề nguồn: - Tôi đã dành rất nhiều thời gian với Hướng dẫn bạn đề cập, nhưng tài liệu cho nguồn là rất VERY ánh sáng. – user2669055
Điểm then chốt mà tôi nghĩ là ở trang p.s. Tôi đã thêm. Đối với một hiệp hội * thông qua * một mô hình tham gia, bạn chỉ cần nói cho nó tên của hiệp hội bạn đang tham gia thông qua (nếu nó không thể được suy ra). Phần còn lại của các tùy chọn không quan trọng. Đó là những liên kết * trực tiếp *. Và đó là tất cả 'nguồn', chỉ định liên kết để sử dụng trên mô hình kết hợp cho một liên kết' thông qua'. – gregates