Scott
Scott

Reputation: 63

Rails has_one with multiple columns - has_many and has_one issue

Trying to come up with a has_one association for this issue. I have two tables:

Ca:
  :id
  :serial
  ...
Cert:
  :id
  :ca_id
  :serial
  ...

There are many certs for a given cas.id but only one cert for a cas(:ca_id, :serial). I don't need the has_many association, but do need the has_one so that I may reference the certificate of the CA using ca.cert. I need the has_one to create something like the following query:

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

To further illustrate the associations between a CA and certificates -

Illustration

Why model it like this? Well, a cert-is-a-cert. Meaning structure and feature are similar whether the cert identifies a CA or an end user.

Seems like has_one would be straight forward but I've tried various approaches using scopes and such to no avail.

Granted I can, and have, created a 'cert()' method in the cas model but it just seems like an association should be possible.

Upvotes: 3

Views: 3005

Answers (1)

Martin M
Martin M

Reputation: 8658

You can define a has_one with a scope:

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

now

Ca.first.cert

gives THE cert with the matching serial.
But is it more elegant or more Rails than defining:

class Ca < ActiveRecord::Base
  has_many :certs
  def cert
    certs.where(serial: serial)
  end
end

Upvotes: 5

Related Questions