如何处理has_many关系中的“同义词”

时间:2014-02-01 23:30:34

标签: ruby-on-rails design-patterns activerecord ruby-on-rails-3.2 associations

这是一个棘手的问题。我有一个Rails关联,但需要添加功能来处理一些特殊情况。

class Item < ActiveRecord::Base
  has_many :notes
end

class Note < ActiveRecord::Base
  belongs_to :item
end

问题是你可能在db中有这样的东西(相同的项目可能在规模或数量上有所不同,但是它们是desc的一部分,并且由于会计软件而无法真正解决):

items 
id    desc
1     a glass something
..
10    a bottle of something
..
20    a case of bottles of something


notes
id   note                           item_id
3    "a note about something"       1

我想要做的是创建一个linke,以便项目1,10和20在加载笔记时都会加载ID为1的笔记

例如:

item1=Item.find(1)
item1.notes[0].id  # 3

item10=Item.find(10)
item10.notes[0].id  # 3

item20=Item.find(20)
item20.notes[0].id  # 3

我觉得应该有一个非常基本的方法来做这个并且正在寻找建议。这很麻烦,但可能会工作的是将一个破折号分隔的other_ids列表写入notes表中,以便notes.other_ids="-10--20-"

class Item < ActiveRecord::Base
  has_many :notes

  def sym_items
    Note.where('other_ids like ?',"%-#{self.id}-%")
  end
end

我们真的只需要在一个场景中处理这个问题,所以一个hacky sol'n woudl可以,但显然会更好。可能做一个has_many:通过。我不确定后者 - 也许增加了太多的复杂性。任何帮助或建议将不胜感激。

THX

1 个答案:

答案 0 :(得分:0)

所以我不确定我是否完全理解这种情况。看起来你可能想要这样的东西:

class Item < ActiveRecord::Base
  has_many :notes
  has_many :other_item_notes
  has_many :other_notes, class_name: "Note", through: :other_item_notes, source: :note
  has_many :other_items, class_name: "Item", through: :notes, source: :other_items
end

class Note < ActiveRecord::Base
  belongs_to :item
  has_many :other_item_notes
  has_many :other_items, class_name: "Item", through: :other_item_notes, source: :item
end

class OtherItemNote < ActiveRecord::Base
  belongs_to :item
  belongs_to :note
end

这里的诀窍是你在项目和笔记之间有多对多的关联(我假设你知道这些其他关联应该如何/为何起作用)。然后,我们使用我们现在可以访问的其他项的关联来访问其关联项。 N + 1查询可能会出现并发症,但其中一些可以通过在您的关联上使用inverse_of来处理。

如果以这种方式执行此操作,则需要查询数据库搜索中的索引id列,而不是上面示例中的字符串比较查询。