Peter
Peter

Reputation: 132157

Nested association/join in rails

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

Answers (3)

Harish Shetty
Harish Shetty

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

Larry K
Larry K

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

Dean Brundage
Dean Brundage

Reputation: 2048

Use default_scope

class Seat
  default_scope includes([:car])
 end

class Car
  default_scope includes([:owner, :seats])
end

Upvotes: 0

Related Questions