Reputation: 15
I have three tables: users
, cars
, and mechanics
.
associations:
I want to find users with cars repaired by a specific mechanic, so I'm doing something like this:
User.joins(:cars).where('cars.color = ? AND cars.type = ? AND cars.mechanic.name = ?', 'green', 'estate', 'paul')
The trick is that I don't know how to write this cars.mechanic.name
part.
Upvotes: 1
Views: 75
Reputation: 15530
An association has_many can be extended with through option, see API docs for more details. Specific to your question Car model belongs to both User and Mechanic, so this should help you:
class User < ActiveRecord::Base
has_many :cars
has_many :mechanics, through: :cars
end
class Mechanic < ActiveRecord::Base
has_many :cars
has_many :users, through: :cars
end
class Car < ActiveRecord::Base
belongs_to :user
belongs_to :mechanic
end
class MechanicsController < ActionController::Base
def show
@mechanic = Mechanic.find_by(name: params[:name])
@users = @mechanic.users.includes(:cars)
end
end
Upvotes: 0
Reputation: 11876
User
.joins( :cars => :mechanic )
.where( :cars => {:color => "green", :type => "estate"},
:mechanic => {:name => "paul"} )
Try this may be this will work.
Upvotes: 2
Reputation: 34774
You need to join in mechanic
as well and then you can query on it:
q = User.joins(cars: :mechanic)
q = q.where('cars.color = ? and cars.type = ?', 'green', 'estate')
q = q.where('mechanics.name = ?', 'paul')
You'll need to watch out though because you are then potentially returning multiple User
instances. If a user has two cars (two green estates) in this example then they will be returned twice by that query. Yo get round that you probably want to add a distinct
on the query too to only return a user once regardless of how many of their green estates Paul may be attending to.
q = q.distinct
Upvotes: 0