开发者

How do I find all of the parasites belonging to the particular pet of a particular user?

Okay, I feel like I'm starting to come to SO for every activerecord query I have to write now and I'm starting to drag out my user/pet/parasite metaphor but here we go again.

In the following setup;

class User < ActiveRecord::Base
  has_many :pets
  has_many :parasites, :through => :pets
end

class Pet < ActiveRecord::Base
  has_many :parasi开发者_Python百科tes
  belongs_to :user
end

class Parasite < ActiveRecord::Base
  belongs_to :pet
end

I want to write a search that will return all of the parasites that belong to Bob's cat (i.e. User.name = 'Bob' and Pet.animal = 'Cat').

I realise I can do this with the fairly drawn out and ugly

User.where(:name => 'Bob').first.pets.where(:animal => 'Cat').first.parasites

but I thought there should be a more succinct way of doing this.

All of my attempts to write a join statement to make this happen result in an ActiveRecord::Configuration error so I suspect I am going about this backwards. Once again, this seems like it should be easier than it is.

Thanks.


You try to achieve a has_many through has_many association. This won't work using Rail's eager loading associations.

What you have to do is:

  • join the users
  • join the pets
  • scope users down by username
  • scope pets down by user_id and the animal field

In ActiveRecord:

Parasite.joins(:pet).joins('INNER JOIN users').where('users.name = ? AND pets.user_id = users.id AND pets.animal = ?', @username, @animal)

Alternatively you can create a named scope:

class Parasite < ActiveRecord::Base
  belongs_to :pet
  scope :parasites_of, lambda {|owner, animal_type| joins(:pet).joins('INNER JOIN users').where('users.name = ? AND pets.user_id = users.id AND pets.animal = ?', owner, animal_type) }
end

Now you can call Parasite.parasites_of('Bob', 'Cat')

The resulting SQL Query will look like:

SELECT * FROM parasites
 INNER JOIN users,
 INNER JOIN pets ON pets.id = parasites.pet_id
WHERE
  users.name = 'Bob'
  AND
  pets.user_id = users.id
  AND
  pets.animal = 'Cat'

(Hint: The .to_sql method will show you the plain SQL query)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜