Как мне найти всех паразитов, принадлежащих конкретному питомцу конкретного пользователя? - PullRequest
3 голосов
/ 29 июля 2011

Хорошо, я чувствую, что начинаю приходить в SO для каждого запроса activerecord, который мне нужно написать сейчас, и я начинаю вытаскивать свою метафору user / pet / parasite, но здесь мы идем снова.

В следующей настройке;

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

class Pet < ActiveRecord::Base
  has_many :parasites
  belongs_to :user
end

class Parasite < ActiveRecord::Base
  belongs_to :pet
end

Я хочу написать поиск, который вернет все паразиты, принадлежащие коту Боба (т. Е. User.name = 'Bob' и Pet.animal = 'Cat').

Я понимаю, что могу сделать это с довольно вытянутым и уродливым

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

, но я подумал, что должен быть более краткий способ сделать это.

Все мои попытки написать оператор соединения, чтобы это произошло, приводят к ошибке ActiveRecord :: Configuration, так что я подозреваю, что я иду в обратном направлении.Еще раз, кажется, что это должно быть проще, чем есть.

Спасибо.

1 Ответ

2 голосов
/ 29 июля 2011

Вы пытаетесь достичь ассоциации has_many through has_many. Это не будет работать при использовании реляционных ассоциаций загрузки Rail.

Что вам нужно сделать, это:

  • присоединиться к users
  • присоединиться к pets
  • объем users вниз на username
  • scope pets down user_id и поле animal

В ActiveRecord:

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

В качестве альтернативы вы можете создать именованную область:

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

Теперь вы можете звонить Parasite.parasites_of('Bob', 'Cat')

Результирующий SQL-запрос будет выглядеть так:

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'

(Подсказка: метод .to_sql покажет вам простой SQL-запрос)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...