问题描述
在我的模式我有一个名为Imprintables模式。在这个模型中我有这样的自我指涉的关系:
In my schema I have a model called Imprintables. In this model I have this self-referential relationship:
class Imprintable < ActiveRecord::Base
has_and_belongs_to_many :coordinates, class_name: 'Imprintable', association_foreign_key: 'coordinate_id', join_table: 'coordinates_imprintables'
...
end
在压印创建/编辑表单我有一个选择字段,用户可以选择的坐标imprintables(坐标用于识别类似于一个正在创建/编辑imprintables)。我的问题是,如果我有一个压印A和与压印B,当我创建一个和名单B作为坐标压印,我希望能够看一下对B编辑表单,看到也被列为一个坐标。
In the imprintable create/edit form I have a select field where users can select coordinate imprintables (coordinates are used to identify imprintables that are similar to the one being created/edited). My issue is that if I have an imprintable A and and imprintable B, when I create A and list B as a coordinate imprintable, I want to be able to look at the edit form for B and see A also listed as a coordinate.
我试过修改控制器的更新和创造行动,两对编号的插入连接器表(coordinates_imprintables)。例如,如果A.id = 1和B.id = 2,则执行某些SQL像:
I've tried modifying the controller's update and create action to insert both pairs of id's into the linker table (coordinates_imprintables). For instance if A.id = 1 and B.id = 2, then executing some sql like:
INSERT INTO coordinates_imprintables (imprintable_id, coordinate_id) VALUES (1, 2)
INSERT INTO coordinates_imprintables (imprintable_id, coordinate_id) VALUES (2, 1)
但我无法得到它的工作,因为我不知道如何当用户试图删除或插入一个坐标知道,我甚至不知道这是正确的答案呢。 Railscasts已略有帮助,这似乎只是一个棘手的情况,因为我有,这也是对称的一种自我指涉的关系的典范。感谢您的时间!
But I couldn't get it working because I'm not sure how to know when a user is trying to delete or insert a coordinate, and I'm not even sure if that's the correct answer anyway. Railscasts have been marginally helpful, this just seems like a tricky case because I have a model with a self-referential relationship that is also symmetrical. Thanks for you time!
推荐答案
您似乎有什么要寻找的是这里的的。这些之前执行,之后或期间对象的生命周期操作。
What you seem to be looking for here are model callbacks. These execute before, after, or during actions in an object's lifecycle.
为了使用这些对于你的情况,你可以为你的 CoordinatedImprintable
表中添加一个模型。之后,当创建,更新或者销毁 coordinate_imprintable
,你需要做同样的事情为它的镜子。
In order to use these for your situation, you can add a model for your CoordinatedImprintable
table. Then, whenever you create, update, or destroy a coordinate_imprintable
, you'll need to do the same thing for its mirror.
class CoordinateImprintable < ActiveRecord::Base
belongs_to :imprintable
belongs_to :coordinate, class_name: 'Imprintable', foreign_key 'imprintable_id'
after_create :add_mirror
after_update :update_mirror
after_destroy :destroy_mirror
def add_mirror
self.class.find_or_create(imprintable: coordinate, coordinate: imprintable)
end
def update_mirror
if self.changed?
mirror = self.class.find(imprintable: coordinate_was, coordinate: imprintable_was)
mirror.update_attributes(imprintable: coordinate, coordinate: imprintable)
end
end
def destroy_mirror
mirror = self.class.find(imprintable: coordinate, coordinate: imprintable)
mirror.destroy if mirror && !mirror.destroyed
end
end
您还需要改变你的 has_and_belongs_to_many
有关两个的has_many:通过
关系
You'll also need change your has_and_belongs_to_many
relation to two has_many :through
relations.
class Imprintable
has_many :coordinate_imprintables
has_many :coordinate, through: :coordinate_imprintables
has_many :mirrored_coordinate_imprintables, class_name: 'CoordinateImprintable', foreign_key: 'coordinate_id'
has_many :mirrored_coordinates, through: :mirrored_coordinate_imprintables, source: :imprintable
end
希望这有助于!并随时与任何问题发表评论。
Hopefully this helps! And feel free to comment with any questions.
这篇关于对称,自引用HABTM关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!