Reputation: 4964
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
Upvotes: 1
Views: 2520
Reputation: 593
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!
Upvotes: 4