我正在处理一个相当简单的has\u many-through:我可以使class\u name/foreign\u键参数在一个方向上工作,但不能在另一个方向上工作。也许你能帮我。(请注意,如果Rails 4存在差异,我将使用它):
一个用户通过ListingManager管理多个列表,一个列表由多个用户通过ListingManager管理。ListingManager有一些数据字段,与这个问题无关,所以我在下面的代码中对它们进行了编辑
以下是最简单的部分:
类用户<;ActiveRecord::Base
有很多:上市经理
拥有多个:列表,通过::列表管理器
终止
类列表<;ActiveRecord::Base
有很多:上市经理
有很多:经理,通过::列出经理,类名:“用户”,外键:“经理id”
终止
类列表管理器<;ActiveRecord::Base
属于:列表
属于:经理,类别名称:“用户”
属性可访问:列表id,:管理者id
终止
从上面可以猜到,ListingManager表如下所示:
创建“列表管理器”表,强制:true do | t|
t、 整数“列表\u id”
t、 整数“管理者id”
终止
所以这里唯一不简单的是ListingManager使用manager\u id而不是user\u id
不管怎么说,上述方法是有效的。我可以调用user.listings获取与该用户关联的列表,也可以调用listing.managers获取与该列表关联的经理
然而(这是问题所在),我认为说user.listings没有太大意义,因为用户也可以“拥有”而不是“管理”列表,所以我真正想要的是user.managed_listings,所以我调整了user.rb
拥有多个:列表,通过::列表管理器
到
拥有多个:托管列表,通过::列表管理器,类名称:“列表”,外键:“列表id”
这与上面listing.rb中的代码完全类似,因此我认为这应该马上就可以实现。相反,我的rspec测试会说
ActiveRecord::HasManyThroughSourceAssociationNotFoundError:
在模型列表管理器中找不到源关联:托管列表或:托管列表。Try“有多个:托管列表,:至=>;:列表_管理者:source=>&书信电报;名称>;'。它是:listing还是:manager?
测试是:
它“管理许多托管的\u列表”的功能
user=FactoryGirl.build(:user)
l1=FactoryGirl.build(:清单)
l2=FactoryGirl.build(:清单)
user.managed_列表<&书信电报;l1
user.managed_列表<&书信电报;l2
期望(@user.managed_listings.size)达到等式2
终止
现在,我确信我什么都不知道。是的,我想我可以做一个别名,但我很担心listing.rb中使用的相同技术在user.rb中似乎不起作用。你能解释一下吗
更新:
我更新了代码以反映@gregates的建议,但我仍然遇到了一个问题:我编写了一个额外的测试,但失败了(并通过Rails控制台中的“手动”测试确认)。当编写这样的测试时:
它“管理许多托管的\u列表”的功能
l1=FactoryGirl.create(:列表)
@user=user.last
ListingManager.destroy\u all
@前\u count=ListingManager.count
期望(@before_count)。等于0
lm=FactoryGirl.create(:listing_manager,manager_id:@user.id,listing_id:l1.id)
期望(@user.managed_listings.count)达到等式1
终止
上述方法失败了。Rails生成错误PG::UnfinedColumn:error:列listing\u managers.user\u id不存在(它应该查找“listing\u managers.manager\u id”)。因此,我认为在关联的用户端仍然存在错误。在user.rb的中有许多:管理的列表,通过::listing\u managers,source::listing,用户如何知道使用manager\u id访问其列表
这里的问题是
有很多:管理者,通过::列出管理者
ActiveRecord可以推断联接模型(:listing_managers)上关联的名称,因为它与您定义的关联具有相同的名称。也就是说,挂牌和挂牌经理都有许多经理
但你的另一个社团却不是这样。在那里,一个列表管理器有许多:列表,但是一个用户有许多:管理的列表。因此ActiveRecord无法推断它应该使用的ListingManager上的关联名称
这就是:source选项的作用(请参阅http://guides.rubyonrails.org/association_basics.html#has-许多协会(参考文献)。因此,正确的声明应该是:
有很多:托管的列表,通过::列表管理器,源::列表
(另一方面,你实际上不需要:外键或:另一个上的class\u name选项有很多:通过。你可以用它们来定义直接的关联,然后有很多:通过就可以指向:通过模型上的正确关联。)