简体   繁体   English

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

[英]How can I join the same 2 models twice in Rails?

I have an app with country preferences. 我有一个具有国家/地区偏好设置的应用程序。 A user will have 2 types of country preferences - event and research. 用户将具有2种国家/地区偏好设置-事件和研究。 In the future there may be more. 将来可能还会更多。 I was leaning more towards having 2 tables to represent this over using STI. 我更倾向于使用2个表来表示这一点,而不是使用STI。 I'm having a bit of trouble configuring Rails elegantly to do this. 我在优雅地配置Rails时遇到了麻烦。 I could hack it but I would rather do this by Rails convention. 我可以修改它,但我更愿意按照Rails的惯例进行操作。 What I want is something like this: 我想要的是这样的:

class User < ActiveRecord::Base
  has_many event_countries, :through => :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

This doesn't work though. 但是,这不起作用。 Given this "pseudo code" does anyone know how to actually implement this in Rails? 有了这个“伪代码”,有人知道如何在Rails中实际实现吗?

I think you're going about declaring them wrong, because this should work properly. 我认为您要声明它们错误,因为这应该可以正常工作。 That's what the :through directive is for: 这就是: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

A lot of the awkwardness comes from the labels you've chosen for the tables. 许多尴尬来自于您为表格选择的标签。 Although they'd seem reasonable at first glance, the way you use them ends up making them difficult. 尽管乍看之下它们似乎很合理,但是使用它们的方式最终使它们变得困难。

You might want to call research_countries something like user_research_countries so that the relationship name can be user.research_countries as the :through : 您可能要调用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

You can refactor this even further by adding a field to the user-country association table that includes one or more flags, which in this case would be research or event or whatever you require later: 您可以通过在用户国家/地区关联表中添加一个包含一个或多个标志的字段来进一步重构该字段,在这种情况下,这将是研究或事件,或者稍后您需要执行任何操作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM