对称,自引用HABTM关系 [英] Symmetrical, self-referential HABTM relationship

查看:119
本文介绍了对称,自引用HABTM关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



在我的模式我有一个名为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关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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