自引用 Rails HABTM 关联仅单向工作



我有文档,其中一些是相关的,关系是对称的。也就是说,我尝试根据 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} 
)}

最新更新