如何在Rails中两次加入相同的2个模型?

我有一个国家偏好的应用程序。 用户将有两种类型的国家偏好 – 事件和研究。 将来可能会有更多。 我更倾向于使用2个表来表示使用STI。 我在执行此操作时优雅地配置Rails有点麻烦。 我可以破解它,但我宁愿通过Rails惯例这样做。 我想要的是这样的:

class User  :event_countries, :class_name => 'Country' has_many research_countries, :through => :research_countries, :class_name => 'Country' end class EventCountry < ActiveRecord::Base belongs_to :country belongs_to :user end class ResearchCountry < ActiveRecord::Base belongs_to :country belongs_to :user end class Country < ActiveRecord::Base ... end 

但这不起作用。 鉴于这个“伪代码”有谁知道如何在Rails中实际实现这一点?

我认为你要宣布他们错了,因为这应该正常工作。 这就是:through指令:

 class User < ActiveRecord::Base has_many :event_countries has_many :countries_with_events, :through => :event_countries, :source => :country has_many :research_countries has_many :countries_with_researches, :through => :research_countries, :source => :country end class EventCountry < ActiveRecord::Base belongs_to :country belongs_to :user end class ResearchCountry < ActiveRecord::Base belongs_to :country belongs_to :user end class Country < ActiveRecord::Base # ... end 

许多尴尬来自于您为表格选择的标签。 虽然乍一看它们看似合理,但你使用它们的方式最终会让它们变得困难。

您可能希望将research_countries称为user_research_countries以便关系名称可以是user.research_countries ,如下所示:through

 class User < ActiveRecord::Base has_many :user_event_countries has_many :event_countries, :through => :user_event_countries, :source => :country has_many :user_research_countries has_many :research_countries, :through => :user_research_countries, :source => :country end class UserEventCountry < ActiveRecord::Base belongs_to :country belongs_to :user end class UserResearchCountry < ActiveRecord::Base belongs_to :country belongs_to :user end class Country < ActiveRecord::Base # ... end 

您可以通过向包含一个或多个标志的用户 - 国家/地区关联表添加字段来进一步重构此操作,在这种情况下,这些标记将是研究或事件或以后需要的任何内容:

 class User < ActiveRecord::Base has_many :user_countries has_many :event_countries, :through => :user_countries, :source => :country, :conditions => { :event => true } has_many :research_countries, :through => :user_countries, :source => :country, :conditions => { :research => true } end class UserCountry < ActiveRecord::Base belongs_to :country belongs_to :user # * column :event, :boolean # * column :research, :boolean end class Country < ActiveRecord::Base # ... end