lobati
lobati

Reputation: 10195

`include`able ActiveRecord association with additional where

I have 3 ActiveRecord models:

class Doc < ActiveRecord::Base
  has_many :fields
  has_many :forms
end

class Form < ActiveRecord::Base
  belongs_to :doc
end

class Field < ActiveRecord::Base
  belongs_to :doc
end

Each of these models has a version column. On Doc it's the most recent version, and on Form and Field it is the version of the doc when they were created. It's easy enough to query for the fields for a given form:

class Form < ActiveRecord::Base
  belongs_to :doc
  has_many :fields, ->(form) { where(version: form.version) }, through: :doc
end

Is there any way for me to construct the relationship between Form and Field such that I can eager load the fields on forms? i.e. I want to be able to say:

doc.forms.includes(:fields)

I'm using Postgres as my data store.

Upvotes: 1

Views: 58

Answers (1)

Albin
Albin

Reputation: 3012

As stated in the conversation above I think it might be hard to solve with a clean activerecord query. And I think that this fact might be a little bit of a smell and might tell you that the way your database is structured might not be optimal.

Given this it can be solved by writing a custom join

has_many :version_fields, -> { joins('INNER JOIN "forms" tmp on "tmp"."version" = "fields"."version"') }, through: :doc, source: :fields

In this code we let the combination of the original join which enforces the id constraint and this custom sql which enforces the version.

Upvotes: 1

Related Questions