【问题标题】:Rails has_many through – how to specify key columns for join table?Rails has_many through - 如何为连接表指定键列?
【发布时间】:2018-05-03 21:59:43
【问题描述】:

tl;博士

我想将 url_id 用于连接表的两列。 Rails 坚持使用文档表中的主键。


我有带有 url_id 属性的自引用 Document 类。一个文档可以引用其他文档。我想要以 url_id 作为连接值的连接表,如下所示:

  • 期望的状态:

    Documents:           Document relationships:
    
    ID | URL_ID |        REFERRING_ID | REFERENCED_ID |          
    ---|--------|        -------------|---------------|
    1  | 1234   |        1234         | 1266          |
    2  | 1266   |        1234         | 2345          |
    3  | 2345   |        1266         | 426           |
    4  | 426    |        444          | 750           |
    5  | 750    |
    7  | 444    |
    

但我无法说服 rails 使用 url_id 作为 referring_id 键。

有了这样的架构,我可以使用类似 SQL 的 sn-p 来获取相关文档。

SELECT "documents".* FROM "documents"
INNER JOIN "document_relationships"
ON "documents"."url_id" = "document_relationships"."referenced_id"
WHERE "document_relationships"."referring_id" = ?

通过ActiveRecord documentation 后我能得到的最接近的是:

  • 实际状态:

    REFERRING_ID | REFERENCED_ID |
    -------------|---------------|
    1            | 1266          |
    1            | 2345          |
    2            | 426           |
    7            | 750           |
    

铌。 Rails 在 referring_id 列中使用 document_id 而不是 url_id

  • 文档类:

    class Document < ApplicationRecord
        has_many :document_relationships, foreign_key: :referring_id
        has_many :related, through: :document_relationships, source: :referenced
    end
    
    class DocumentRelationship < ApplicationRecord
        belongs_to :referring, class_name: "Document"
        belongs_to :referenced, class_name: "Document", primary_key: :url_id
    end
    

【问题讨论】:

  • 是不是像亲子关系?

标签: sql ruby-on-rails activerecord


【解决方案1】:

您必须在 document_relationships - referring 关联的两端设置 primary_key:

class Document < ApplicationRecord
  has_many :document_relationships, foreign_key: :referring_id, primary_key: :url_id
  has_many :related, through: :document_relationships, source: :referenced
end

class DocumentRelationship < ApplicationRecord
  belongs_to :referring, class_name: "Document", primary_key: :url_id
  belongs_to :referenced, class_name: "Document", primary_key: :url_id
end

# In case the url_id is not unique do not forget to use sth like Array's #uniq :
# Document.first.related.to_a.uniq(&:url_id)

【讨论】:

  • 就是这样!我尝试将主键添加到第一个 belongs_to 关系中,但我没有想到我也需要将其放入 has_many 部分。
猜你喜欢
  • 1970-01-01
  • 2013-04-22
  • 2015-02-01
  • 1970-01-01
  • 2013-07-07
  • 2012-02-11
  • 2011-01-06
  • 2013-09-18
  • 2019-03-04
相关资源
最近更新 更多