我正在处理一个相当简单的 has_many through: 情况,我可以使 class_name/foreign_key 参数在一个方向上工作,但不能在另一个方向上工作。也许你能帮帮我。(如果有差异,我正在使用 Rails 4):
英文:一个User通过ListingManager管理多个Listing,一个Listing由多个User通过ListingManager管理。列表管理器有一些数据字段,与这个问题无关,所以我在下面的代码中编辑了它们
这是有效的简单部分:
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
正如您可以从上面的 ListingManager 表中猜到的那样:
create_table "listing_managers", force: true do |t|
t.integer "listing_id"
t.integer "manager_id"
end
所以这里唯一不简单的是ListingManager使用manager_id
而不是user_id
无论如何,上述工作。我可以调用user.listings
以获取与用户关联的列表,也可以调用listing.managers
以获取与列表关联的经理。
但是(这是问题所在),我认为这样说并没有太大意义,user.listings
因为用户也可以“拥有”而不是“管理”列表,我真正想要的是user.managed_listings
所以我调整user.rb
以更改 has_many :listings,通过: : list_managers 到 has_many :managed_listings,通过: :listing_managers, class_name: "Listing", foreign_key: "listing_id"
这与上面的代码完全类似listing.rb
,所以我认为这应该可以正常工作。相反,我对这个 barfs 的 rspec 测试是这样说的
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?
测试是:
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
现在,我确信我什么都不知道。是的,我想我可以做一个别名,但我很烦恼在 中使用的相同技术listing.rb
似乎不适用于user.rb
. 你能帮忙解释一下吗?
更新:我更新了代码以反映@gregates 的建议,但我仍然遇到问题:我编写了一个失败的附加测试(并通过 Rails 控制台中的“手动”测试确认)。当一个人编写这样的测试时:
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
以上失败。Rails 生成错误PG::UndefinedColumn: ERROR: column listing_managers.user_id does not exist
(它应该在寻找“listing_managers.manager_id”)。所以我认为关联的用户端仍然存在错误。在user.rb
'shas_many :managed_listings, through: :listing_managers, source: :listing
中,用户如何知道使用manager_id
它来访问其列表?