Запросить записи через отношение own_to в Rails

У меня есть модель действий, и они принадлежат местоположению

Как выбрать все виды деятельности, у которых location.country = Australia? (Например)

Могу ли я сделать это в рамках области?


person Will    schedule 02.01.2013    source источник


Ответы (3)


С последними версиями рельсов вы можете:

Activity.joins(:location).where(locations: { country: "Australia" })

Остерегаться:

  • это местоположение (единственное число) в joins(:location), поскольку оно ссылается на belongs_to название отношения
  • это местоположения (множественное число) в where(…), поскольку оно ссылается на имя таблицы

Последнее означает, что если у вас было следующее:

belongs_to :location, class_name: "PublicLocation"

запрос будет:

 Activity.joins(:location).where(public_locations: { country: "Australia" })
person Arnaud    schedule 21.10.2015
comment
Уточнение относительно именования в единственном и множественном числе, когда дело доходит до принадлежности к имени таблицы, проясняет это для меня. Спасибо! - person boyan; 21.10.2016

Тип запроса, о котором вы говорите, - это соединение. Вы можете попробовать такие запросы в консоли, например:

Activity.joins(:locations).where('locations.country = "Australia"')

Это означает, что SQL возьмет все действия и местоположения, связанные с этим, найдет местоположения, где страна = Австралия, а затем вернет вам действия, связанные с этими местоположениями.

Чтобы сделать это более пригодным для повторного использования, определите его в своей модели с помощью переменной для страны:

scope :in_country, lambda {|country| joins(:locations).where('locations.country = ?',country)}

Подробнее об этом можно узнать в документах по API.

person Andrew    schedule 02.01.2013
comment
Хорошо, спасибо за это. Я не понимал, что мне нужно указать соединение, прежде чем я смогу выполнить запрос. рискуя lmgtfy, где документы для этого? Я осмотрелся и не нашел хороших ресурсов, должно быть, упустил что-то очевидное. - person Will; 02.01.2013
comment
кстати, я добавил редактирование, чтобы сопоставить переменную, передаваемую в лямбда, с переменной страны, используемой внутри - person Will; 02.01.2013
comment
Отлично, спасибо за редактирование. Кроме того, обратите внимание на другой ответ, который предполагает, что если вы собираетесь использовать объект местоположения, вы также можете включить его. Наконец, re: docs, это SQL, а не Rails. Поэтому трудно найти простую документацию с практическими рекомендациями для такого рода использования SQL, специфичного для Rails, но любой учебник/справочник по SQL может быть полезен. IMO обучение владению SQL — самая сложная часть освоения Rails. Удачи! - person Andrew; 02.01.2013
comment
Я удивлен, что это работает, так как :location во множественном числе, и кажется, что эта связь не существует. - person Jeremy Thomas; 08.12.2016

Да, прицел можно использовать. Что-то вроде этого должно работать в модели Activity:

scope :down_under, 
    joins(:locations).
    where("locations.country = 'Australia')
person Dave S.    schedule 02.01.2013
comment
Вам не нужны оба объединения и включения для выполнения этого запроса. Если он просто загружает действия, нет необходимости включать все местоположения вместе с запросом. - person Andrew; 02.01.2013
comment
Хороший момент - включение не является строго необходимым. Однако, если ему действительно нужен объект местоположения, он может сэкономить себе путь к БД туда и обратно. - person Dave S.; 02.01.2013
comment
Спасибо за это. включает, чтобы избежать n+1. - person Will; 03.01.2013