Alex Antonov
Alex Antonov

Reputation: 15146

rails 4 eager loading heavy association

I have an association between rails models.

There are three models which describe product properties:

Property is associating the models, each property has a name and value.

class Property < AR::Base
  belongs_to :product
  belongs_to :property_name
  belongs_to :property_value

class PropertyName < AR::Base
  has_many :properties
  validates :name, presence: true, uniqueness: true

class PropertyValue < AR::Base
  has_many :properties
  validates :value, presence: true, uniqueness: true

After searching via thinking-sphinx I get facets - property_values id & property_names id collections.

Using that result, I then try to find all properties for current list of products (to continue to filter those search results).

In the controller I use:

@property_names = PropertyName
  .where(id: property_name_ids)
  .includes(:property_values).where('property_values.id IN (?)', property_value_ids)

My view:

- @property_names.each do |property_name|
  h4 = property_name.name
  - property_name.property_values.pluck(:value).uniq.each do |property_value|
    = check_box_tag ...
    = label_tag ...

So, eager load does not work. Rails generate a lot of (n+1) queries for the database. What's going wrong? Why includes don't work?

Upvotes: 0

Views: 1000

Answers (2)

Alex Antonov
Alex Antonov

Reputation: 15146

Solved by me.

First of all, add a association has_many :property_values, -> { uniq }, through: :properties at property_names.

After that, I use this query:

  @property_names = PropertyName.where(id: property_name_ids).where.not(name: PropertyName.description)
    .includes(:property_values).where(property_values: { id: property_value_ids }).order('property_values.value')

All works!

Upvotes: 2

socjopata
socjopata

Reputation: 5095

You seem to be including an association which is not defined, as PropertyName doesn't have the a 'property_values' relation defined.

You may want to do something like:

 PropertyName.includes(properties: :property_value)

Upvotes: 0

Related Questions