在我的架构中,我有一个名为Imprintables的模型。在这个模型中,我有这种自我指涉关系:
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类似的imprintables)。我的问题是,如果我有一个可以打印的A和可打印的B,当我创建A并将列表B作为一个可以打印的坐标时,我希望能够查看B的编辑表单并查看A也列为坐标。 / p>
我尝试修改控制器的更新并创建操作以将两对id插入到链接器表(coordinates_imprintables)中。例如,如果A.id = 1且B.id = 2,则执行一些sql,如:
INSERT INTO coordinates_imprintables (imprintable_id, coordinate_id) VALUES (1, 2)
INSERT INTO coordinates_imprintables (imprintable_id, coordinate_id) VALUES (2, 1)
但我无法让它工作,因为我不知道如何知道用户何时尝试删除或插入坐标,我甚至不确定这是否是正确的答案。 Railscasts略有帮助,这似乎是一个棘手的案例,因为我有一个具有自我指涉关系的模型也是对称的。谢谢你的时间!
答案 0 :(得分:1)
您在这里寻找的是model callbacks。它们在对象生命周期中的操作之前,之后或期间执行。
为了在您的情况下使用这些,您可以为CoordinatedImprintable
表添加模型。然后,无论何时创建,更新或销毁coordinate_imprintable
,您都需要为其镜像执行相同的操作。
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 :through
关系。
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
希望这有帮助!如有任何问题,请随时发表评论。