多个关联到同一个模型 [英] Multiple Associations to Same Model

查看:120
本文介绍了多个关联到同一个模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个,我想指定类别如下:

I have two classes that I would like to specify as follows:

class Club < ActiveRecord::Base
  belongs_to :president, :class_name => "Person", :foreign_key => "president_id"
  belongs_to :vice_president, 
             :class_name => "Person",
             :foreign_key => "vice_president_id"
end

class Person < ActiveRecord::Base
  has_one :club, :conditions => 
  ['president_id = ? OR vice_president_id = ?', '#{self.id}', '#{self.id}']
end

试图从人的对象,俱乐部的关联时,这并不工作,给我一个错误。这个错误是因为正在寻找在俱乐部表为person_id当我看着SQL。我可以绕过它宣布多个HAS_ONE协会,但觉得这是做这件事的方式不当。

This doesn't work and gives me an error when trying to get the club association from the person object. The error is because is looking for person_id in the club table when I looked at the SQL. I can get around it by declaring multiple has_one associations, but feel like this is the improper way of doing it.

一个人只能有一个俱乐部的president或副president。

A person can only be the President or Vice President of one club.

任何人都可以提供咨询的一点点关于这个问题,我会非常AP preciative。

Anyone able to offer a little bit of advice on this issue, I would be very appreciative.

推荐答案

HAS_ONE 情况绝不会在工作Rails的,据我所知。

Your has_one condition will never work in Rails, as far as I know.

您需要一个明确的 HAS_ONE belongs_to的或按链接,这两个表的has_many。所以,如果你有两个三通,则需要两个 HAS_ONE 和两个 belongs_to的。这是如何工作的。

You need one explicit has_one or belongs_to or has_many per "link", on both tables. So if you have two "links", you need two has_one and two belongs_to. That is how it works.

其次,我认为你应该重新考虑你的模型。你正在做的方式,一个人不可能是president俱乐部和雇员,在同一时间。或者是两家具乐部的president。即使你没有这些,现在,他们可以进来以后 - 它更容易保持灵活性,现在

Secondly, I think you should reconsider your models. The way you are doing it, one person can not be the president of a club and an employee, at the same time. Or be the president of two clubs. Even if you don't have these right now, they can come in the future - it is easier to stay flexible right now.

这样做的一个灵活的方法是使用的has_many:通过与中间表,指定的作用。换句话说:

A flexible way of doing this is using a has_many :through with an intermediate table that specifies the role. In other words:

# The memberships table has a person_id, club_id and role_id, all integers

class Membership < ActiveRecord::Base
  belongs_to :club
  belongs_to :person
  validates_presence_of :role_id
  validates_numericality_of :role_id
end

class Club < ActiveRecord::Base
  has_many :memberships, :dependent => :delete_all
  has_many :people, :through => :memberships
end

class Person < ActiveRecord::Base
  has_many :memberships, :dependent => :delete_all
  has_many :clubs, :through => :memberships
end

现在,假设ROLE_ID = 0表示员工,ROLE_ID = 1表示president,并ROLE_ID = 2表示vice_ president,你可以使用这样的:

Now, assuming that role_id=0 means employee, role_id=1 means president, and role_id=2 means vice_president, you can use it like this:

tyler = Person.find(1) # person_id is 1
other = Person.find(2) # person_id is 2
c = Club.find(1)  # club_id is 1

tyler.clubs # returns all the clubs this person is "member" of
c.people # returns all the "members" of this club, no matter their role

#make tyler the president of c
tyler.memberships.create(:club_id => 1, :role_id => 1)

#make other the vicepresident of c
#but using c.memberships instead of other.memberships (works both ways)
c.memberships.create(:person_id => 2, :role_id => 1)

#find the (first) president of c
c.memberships.find_by_role_id(1).person

#find the (first) vicepresident of c
c.memberships.find_by_role_id(2).person

#find all the employees of c
c.memberships.find_all_by_role_id(0).collect { |m| m.person }

#find all the clubs of which tyler is president
tyler.memberships.find_all_by_role_id(1).collect { |m| m.club }

其他注意事项:

Additional notes:

  • 您可以用一个角色表和型号补充这一点。角色本来只是AA名,角色会 have_many 的关系,会员将 belong_to 的作用。或者,你可以定义为获取角色名称(如果为0,则返回雇员的成员方法,如果为1,president等
  • 您可以在memberhips所以不超过1人可在给定的俱乐部,或者在同一家具乐部同一名员工的president两次加验证。后来,如果你开始得到特殊情况下,其中一人需要在两个地方,你就只能去适应你的验证。
  • You could complement this with a roles table and model. Roles would have just a a name, roles would have_many relationships and memberships would belong_to role. Or, you could define methods in memberships for getting the role name (if 0, it returns "employee", if 1, "president", etc
  • You can add validations on memberhips so no more than 1 person can be made president of a given club, or the same employee on the same club twice. Later on, if you start getting "exceptional cases" in which a person needs to be in two places, you will just have to adapt your validations.

这篇关于多个关联到同一个模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆