1

I have the following "Query" using ActiveRecord:

Product.joins(product_attr_vals: [attr_val: [:attr]])
       .joins(:product_model)
       .where(product_models: {id: @product_model.id}, attrs: {id: attr.id})
       .distinct
       .count

I am not being able to understand why sometimes, in joins(), rails accept the table name in plural and others in singular.

  • product_attr_vals: (does not work if in singular -> product_attr_val)
  • attr_val:
  • :attr
  • :product_model

Some info:

models/product_model_attr_val.rb

class ProductModelAttrVal < ApplicationRecord
  validates :product_model_id, uniqueness: { scope: :attr_val_id }

  belongs_to :product_model
  belongs_to :attr_val
end

db/migrate/db_creation.rb

create_table :product_model_attr_vals do |t|
  t.references :product_model, null: false, foreign_key: true
  t.references :attr_val, null: false, foreign_key: true

  t.timestamps
end
Augusto Carmo
  • 4,386
  • 2
  • 28
  • 61
  • related: https://stackoverflow.com/questions/23633301/how-to-query-a-model-based-on-attribute-of-another-model-which-belongs-to-the-fi/23633352#23633352 (`joins`/`includes`/`preload` vs `where`: when to use relation name and when to use table's name) – MrYoshiji Mar 25 '18 at 23:12

1 Answers1

4

The answer to when to use singular or plural lies in the name of the association. Usually has_many associations are named in plural, whereas belongs_to associations are named in singular. Behind the scenes when building the query ActiveRecord will make sure to always use the right table name (plural). In Rails there is the concept of "convention over configuration", which means a lot of stuff have a predefined approach that will work out of the box. E.g. take an association belongs_to :product. ActiveRecord will look for a column product_id in the table products and use it to load the product. Another example, has_many :products - ActiveRecord will look for a table called products and assume it has a column your_model_id. Thus it will load all the products for you model instance.

Back to your question, when to use singular or plural. If you are not sure, check your association definition in the respective model. In general, has_many associations use plural, belongs_to associations use singular. Here is an example with two models:

class Employee
  has_many :tasks
end

class Task
  belongs_to :employee
end

And here are some joins examples:

Employee.joins(:tasks) # plural due to has_many 
Task.joins(:employee) # singular due to belongs_to

Hope it was helpful!

Enrai
  • 593
  • 3
  • 10