创建关联以获取同一表的相关记录

时间:2014-12-27 00:55:31

标签: ruby-on-rails ruby

在Ruby 2.1.3 / Rails 3.2.17中,我有以下两个示例类。

班级subject

class Subject < ActiveRecord::Base
  has_many :subject_ors # how to specify??
  has_many :alternates  # how to specify??

  # == Schema Information
  #
  # Table name: subjects
  #
  #  id       :integer(4)      not null, primary key
  #  name     :string(255)
end

班级subject_ors

class SubjectOr < ActiveRecord::Base
  belongs_to :left_subject,  foreign_key: :left_id,  class_name: 'Subject'  # don't really need this
  belongs_to :right_subject, foreign_key: :right_id, class_name: 'Subject'  # don't really need this

  # == Schema Information
  #
  # Table name: subject_ors
  #
  #  id       :integer(4)      not null, primary key
  #  left_id  :integer(4)
  #  right_id :integer(4)
end

SubjectOr的设计意图是与Subject的关系无关紧要,可以被引用为&#34; left&#34;或&#34;对&#34;。也就是说,如果给定的SubjectOr{ :id => 1, :left_id => 2, :right_id => 3 },那么暗示受试者[id:3]会将受试者[id:2]视为替代,就像受试者[id:2]会看到的那样主题[id:3]作为替代,不需要在SubjectOrs中使用对称记录。

我想在名为Subject的{​​{1}}中创建一个关联,找到给定:alternates的其他Subjects。发现还不够,或者我可以使用以下关联:

Subject

这将查找记录(实际上只是一个被黑客攻击的范围),但不允许我做has_many :alternates, class_name: 'Subject', finder_sql: proc { 'SELECT DISTINCT subjects.* ' + 'FROM subjects ' + 'LEFT JOIN subject_ors AS _left ' + 'ON _left.left_id = subjects.id ' + 'LEFT JOIN subject_ors AS _right ' + 'ON _right.right_id = subjects.id ' + "WHERE #{id} IN (_left.right_id, _right.left_id)" } 之类的事情或做ActiveView表单操作(例如{ {1}})。由于同样的原因,范围不会起作用。

如果我可以让.pluck[:id]看到多个外键用于单个关联,然后将其用于{{1},我会在accepts_nested_attributes_for内打开这个特殊关联。 SubjectOr中的关系。 (似乎更适合belongs_to,但此时我并不挑剔。)

基本上,如果我可以控制关​​联的基础查询(除了查找记录之外),我想我可以使它工作。

我尝试过的一些事情:

  • has_many - 不会给我一个完整关联的所有功能;
  • Subject中,Subject的多个目标,以及&#39; SubjectOr.left_subject&#39;和&#39; SubjectOr.right_subject&#39;是同时的关联选择(似乎不可能);
  • finder_sql中,单个Subject关联的多个外键(不允许);
  • 特别&#34; stabby&#34;条件,但似乎不允许自我引用has_many :through记录SubjectOr

belongs_to基本上只是Subject上的一个联接表,但由于我希望它能够在给定的SubjectOr`记录的两个方向上工作,而不是父子关系,所以这就是结果令人惊讶的困难。

我开始越过头脑做一些事情,比如重写&#39; load_target&#39;或添加关联扩展等因为我不确定副作用。

在我去那儿之前,看起来我错过了一些明显的解决方法吗?

谢谢! 理查德

0 个答案:

没有答案