Rails has_one 具有多列 - has_many 和 has_one 问题

Sco*_*ott 3 ruby-on-rails associations

试图为这个问题提出一个 has_one 关联。我有两张桌子:

Ca:
  :id
  :serial
  ...
Cert:
  :id
  :ca_id
  :serial
  ...
Run Code Online (Sandbox Code Playgroud)

给定的 cas.id 有许多证书,但 cas(:ca_id, :serial) 只有一个证书。我不需要 has_many 关联,但需要 has_one 以便我可以使用 ca.cert 引用 CA 的证书。我需要 has_one 来创建类似以下查询的内容:

SELECT * FROM certs 其中 ca_id = {ca.id} AND serial = {ca.serial}

为了进一步说明 CA 和证书之间的关联 -

  • 单个 CA 拥有标识其自身的证书
  • 单个 CA 拥有多个颁发给最终用户的证书
  • CA 根据自己的顺序颁发证书。为简单起见,从 1 开始(CA 的证书序列号为 1,CA 颁发的最终用户证书将从 2 开始)。
  • 证书通过 :ca_id 和 :serial 属于 CA
  • 存储多个 CA。这意味着两个证书可以具有相同的序列号,但属于两个不同的 CA。

插图

为什么要这样建模呢?好吧,证书就是证书。无论证书标识的是 CA 还是最终用户,含义结构和功能都是相似的。

看起来 has_one 很简单,但我已经尝试了使用范围的各种方法,但无济于事。

当然,我可以并且已经在 cas 模型中创建了一个“cert()”方法,但似乎关联应该是可能的。

Mar*_*n M 5

可以定义一个具有范围的 has_one :

class Ca < ActiveRecord::Base
  has_many :certs
  has_one :cert, ->{ joins(:ca).where('cas.serial = certs.serial')}
end

class Cert < ActiveRecord::Base
  belongs_to :ca
end
Run Code Online (Sandbox Code Playgroud)

现在

Ca.first.cert
Run Code Online (Sandbox Code Playgroud)

给出具有匹配序列的证书。
但它比定义更优雅或更Rails吗:

class Ca < ActiveRecord::Base
  has_many :certs
  def cert
    certs.where(serial: serial)
  end
end
Run Code Online (Sandbox Code Playgroud)