我有文档,其中一些是相关的,关系是对称的。也就是说,我尝试根据 HABTM 指令对关联和连接表对这种关系进行建模。
我可以对文档的两个实例执行d1.related_documents << d2
操作。d1.related_documents
工作并返回相关文档,但d2.related_documents
返回一个空集。
我声明了如下表和模型:
-
文档表
create_table :documents do |t| t.string :matter t.string :url_id, unique: true t.text :body t.timestamps end
-
连接表
create_join_table :documents, :documents, table_name: :related_documents, id: false do |t| t.references :referent, foreign_key: { to_table: :documents, primary_key: :url_id }, index: true t.references :reference, foreign_key: { to_table: :documents, primary_key: :url_id }, index: true end end
-
模型
has_and_belongs_to_many :related_documents, join_table: :related_documents, class_name: "Document", foreign_key: :referent_id, association_foreign_key: :reference_id
自我引用的habtm有点超出标准的Rails工具箱。您需要调整finder_sql或有 2 个关系:
has_and_belongs_to_many :related_documents, join_table: :related_documents,
class_name: "Document",
foreign_key: :referent_id,
association_foreign_key: :reference_id
has_and_belongs_to_many :referenced_documents, join_table: :related_documents,
class_name: "Document",
foreign_key: :reference_id,
association_foreign_key: :referent_id
如果您需要将结果合并为一个 SQL,则需要调整 Finder-SQL,例如 https://gist.github.com/srpouyet/4121517
has_and_belongs_to_many :related_documents,
class_name: 'Document',
join_table: :related_documents,
foreign_key: :reference_id,
association_foreign_key: :referent_id,
uniq: true,
finder_sql: proc {
%(SELECT DISTINCT "documents".* FROM "documents"
INNER JOIN "related_documents"
ON "documents"."id" = "related_documents"."referent_id"
WHERE "related_documents"."reference_id" = #{id}
UNION
SELECT DISTINCT "documents".* FROM "documents"
INNER JOIN "related_documents"
ON "documents"."id" = "related_documents"."reference_id"
WHERE "related_documents"."referent_id" = #{id}
)}