ActiveRecord 中与多个自联接的多对多关联
我正在尝试通过自连接实现同一模型的记录之间的多种关系(基于 @Shtééf 的回答)。我有以下模型
create_table :relations, force: true do |t|
t.references :employee_a
t.string :rel_type
t.references :employee_b
end
class Relation < ActiveRecord::Base
belongs_to :employee_a, :class_name => 'Employee'
belongs_to :employee_b, :class_name => 'Employee'
end
class Employee < ActiveRecord::Base
has_many :relations, foreign_key: 'employee_a_id'
has_many :reverse_relations, class_name: 'Relation', foreign_key: 'employee_b_id'
has_many :subordinates, through: :relations, source: 'employee_b', conditions: {'relations.rel_type' => 'manager of'}
has_many :managers, through: :reverse_relations, source: 'employee_a', conditions: {'relations.rel_type' => 'manager of'}
end
通过此设置,我可以成功访问每条记录的下属和经理列表。但是,我很难通过以下方式创建关系。
e = Employee.create
e.subordinates.create
e.subordinates #=> []
e.managers.create
e.managers #=> []
问题是它没有设置关系类型,所以我必须写
e = Employee.create
s = Employee.create
e.relations.create employee_b: s, rel_type: 'manager of'
e.subordinates #=> [#<Employee id:...>]
我做错了什么吗?
I am trying to implement multiple relations between records of the same model via self-joins (based on @Shtééf's answer). I have the following models
create_table :relations, force: true do |t|
t.references :employee_a
t.string :rel_type
t.references :employee_b
end
class Relation < ActiveRecord::Base
belongs_to :employee_a, :class_name => 'Employee'
belongs_to :employee_b, :class_name => 'Employee'
end
class Employee < ActiveRecord::Base
has_many :relations, foreign_key: 'employee_a_id'
has_many :reverse_relations, class_name: 'Relation', foreign_key: 'employee_b_id'
has_many :subordinates, through: :relations, source: 'employee_b', conditions: {'relations.rel_type' => 'manager of'}
has_many :managers, through: :reverse_relations, source: 'employee_a', conditions: {'relations.rel_type' => 'manager of'}
end
With this setup I can successfully access the lists of subordinates and managers for each record. However, I have difficulties to create relations in the following way
e = Employee.create
e.subordinates.create
e.subordinates #=> []
e.managers.create
e.managers #=> []
The problem is that it does not set type of relations, so I have to write
e = Employee.create
s = Employee.create
e.relations.create employee_b: s, rel_type: 'manager of'
e.subordinates #=> [#<Employee id:...>]
Am I doing something wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您可以在 has_many 关联上使用
before_add
和before_remove
回调:这应该有效,并使您能够使用
employe.managers.create
您可能希望在回调中使用
build
而不是create
您还可以阅读有关此解决方案的此问题
You can use
before_add
andbefore_remove
callback on the has_many association :This should works and make you able to use
employe.managers.create
You may want to use
build
instread ofcreate
in the callbackAlso you can read this question about this solution
为了创建多个多对多自联接关联,我建议使用多个表来管理连接可能更有意义。这样,从数据的角度来看,到底发生了什么就非常清楚,从逻辑的角度来看也很清楚。因此,沿着这些思路:
这样,从编码的角度来看,它不会变得比必要的更加复杂,并且您可以使用标准集合访问它,并且它将适当地为您设置连接,而无需您管理它们。因此,这两个集合都应该有效。
并且您不必管理任何其他变量。有道理吗?它添加了一个表格,但提高了清晰度。
In order to create a multiple many-to-many self-join association, I would recommend that it might make more sense to have multiple tables to manage the connection. That way it's very clear from a data standpoint as to exactly what is going on, and it's also clear from a logic standpoint. So something along these lines:
This way it doesn't get any more convoluted than necessary from a coding standpoint, and you can access it using the standard collections and it will appropriately set up your connections for you without you having to manage them. So, both of these collections should work..
And you could not have to manage any other variables. Make sense? It adds a table, but improves clarity.
我将按如下方式重做您的模型:
现在您可以执行以下操作:
注意:当一个人被迫向两位经理汇报时,这通常是一个人离开公司的标志:-)
I would redo your models as follows:
Now you can do the following:
Note: It is usually a sign for one to leave the company when they are made to report to two managers :-)
鉴于所提出的关系,
尽管解决方案有效 - 我对将关联与“rel_type”联系起来感到有点困惑。在这种情况下 - 我想说 rel_type 是多余的,关系应该映射如下:
在这种情况下,关联映射应该更简单一些。
Given the presented relation
Although the solution works - I'm a bit confused by tying the associations with "rel_type". In this case - I'd say the rel_type is redundant and the relation should be mapped as follows:
In such case, the association mapping should be a tad simpler.