在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
关联的多个外键(不允许); has_many :through
记录SubjectOr
。 belongs_to
基本上只是Subject
上的一个联接表,但由于我希望它能够在给定的SubjectOr`记录的两个方向上工作,而不是父子关系,所以这就是结果令人惊讶的困难。
我开始越过头脑做一些事情,比如重写&#39; load_target&#39;或添加关联扩展等因为我不确定副作用。
在我去那儿之前,看起来我错过了一些明显的解决方法吗?
谢谢! 理查德