Reputation: 132157
I have a seat
object that has a car
object that has a owner
that has a name
. I want to display the car
brand
and the car
's owner
's name
together. How do I do this in one query?
eg:
class Seat < ActiveRecord::Base
belongs_to :car
def description
"I am in a #{car.brand} belonging to #{car.owner.name}"
# --> how do I replace this with one query?
end
end
I'll note that this is a highly contrived example to simplify my question. I'm doing this thousands of times in a row, hence the need for more efficiency.
Upvotes: 2
Views: 467
Reputation: 64363
Let us say you are trying to query the Seat
model, and you want to eager load the car and owner objects, you can use the includes
clause.
Seat.includes(:car => :owner).where(:color => :red).each do |seat|
"I am in a #{seat.car.brand} belonging to #{seat.car.owner.name}"
end
Upvotes: 3
Reputation: 49104
For multi-table joins that are often used in my application, I create a View in MySQL. Then create an ActiveRecord Rails model based on the view.
Depending on the SQL statement that powers the view, MySQL may even let the View be read/write. But I just go the simple route and always treat the view as being read-only. You can set the AR model as read only.
By using the Active Record model which uses the view, you get quick single query reads of the database. And they're even faster than normal since MySQL computes the SQL "plan" once for the view, enabling faster use of it.
Remember to also check that your foreign keys are all indexed. You don't want any table scans.
Upvotes: 0
Reputation: 2048
Use default_scope
class Seat
default_scope includes([:car])
end
class Car
default_scope includes([:owner, :seats])
end
Upvotes: 0