You probably use has_many
relationships very often. This stuff is very useful and helps to reflect a lot of relationships from the real world. For example, a car has many parts:
class Car < ApplicationRecord
has_many :parts
end
On database level, the Parts table should have a link to the Car table, usually some sort of foreign key ( car_id column in the Parts table).
But what if you need to create a has_many
relationship by two columns?
Let's imagine that we have next: except Car, there are next models:
class Inventory < ApplicationRecord
# it stores all possible parts that we can use for your cars
end
class CarInventory < ApplicationRecord
# join model
belongs_to :car
belongs_to :inventory
end
class Analogs < ApplicationRecord
belongs_to :car
belongs_to :inventory
has_many :inventories
end
Our task is to be able to get all analogs for a specific detail.
The simplest way is just to add a link to the CarInventory
in Analog
model - create a database migration and probably data migration).
But we use pure SQL we can fetch required data without any changes:
SELECT *
FROM Analogs as an
JOIN CarInventory as ci on ci.inventory_id = an.inventory_id and ci.car_id = an.car_id
WHERE ci.car = <car_id> and ci.inventory_id = <inv_id> and ci.id = <car_inventory.id>
In order to achieve this we can write the next code:
# in CarInventory model
has_many :analogs, ->(car_inventory) do
Analog.where(car: car_inventory.car, inventory: car_inventory.inventory)
end, through: :Inventory
The example probably doesn't reflect real life but I hope can reveal the idea.
Top comments (0)