Ответ 1
Рассмотрим следующие модели (и использование has_many через):
class Reading < ActiveRecord::Base
belongs_to :region,
inverse_of: :readings
end
class Region < ActiveRecord::Base
has_many :readings,
inverse_of: :region
has_many :stores,
inverse_of: :region
end
class Store < ActiveRecord::Base
belongs_to :region,
inverse_of: :stores
belongs_to :manager,
inverse_of: :stores
end
class Manager < ActiveRecord::Base
has_many :stores,
inverse_of: :region
has_many :emails,
inverse_of: :manager
has_many :regions,
through: :stores
has_many :readings,
through: :regions
end
class Email < ActiveRecord::Base
belongs_to :manager,
inverse_of: :emails
end
Теперь ваш вопрос немного неоднозначен, потому что вы говорите, что хотите получить показания для менеджера, но ваш SQL вообще не выбирает показания, а также предписывает область.
Предполагая, что вы хотите, чтобы все чтения соответствовали заданному диспетчеру и региону:
@readings = Reading.joins(region: { stores: :manager }).where(
manager: { name: 'John Smith' },
region: { id: 1234567 })
Предполагая, что вы также хотите загружать регионы, магазины и менеджеры, чтобы избежать запросов 1 + N:
@readings = Reading.includes(region: { stores: :manager }).where(
manager: { name: 'John Smith' },
region: { id: 1234567 })
Предполагая, что у вас есть имя менеджера и вы хотите как их данные, так и показания:
@manager = Manager.where(name: 'John Smith').first!
@readings = manager.readings
Все приведенные выше примеры запросов возвращают ActiveRecord::Relation
, которые могут быть дополнительно привязаны к условиям where
или joins
, limit
, group
, having
и order
и т.д.
Вы также должны учитывать различия методов joins
, includes
, preload
, eager_load
и references
. Здесь есть краткая информация . Я бы посоветовал вам читать документы, руководства и блоги об Arel, поскольку он поддерживает объединения и псевдонимы.
После использования ActiveRecord в гневе какое-то время я пришел к выводу, что Sequel/SequelModel намного лучше DB/ORM, чем ActiveRecord. Никакое неуважение к разработчикам, но я обнаружил, что Sequel - лучший инструмент. У Arel есть тонкая документация в течение многих лет, и у ActiveRecord/Arel есть недостатки в ряде областей, таких как условия соединения, контроль типов соединений и нетерпеливая загрузка, объединения, пересечения, рекурсивные запросы, списки деревьев/смежности и многие другие функции SQL, которые Sequel покрывает.
Поскольку вы, кажется, только начинаете с AR, возможно, захотите вместо этого начать с Sequel, чем бороться со слабыми местами и разочарованиями запросов ActiveRecord, включая разрозненное использование AR и Arel, отношений с ассоциациями и странностей запросов, это продолжается и продолжается. Нет ничего более неприятного, чем знание SQL, которое вы хотите, но ActiveRecord/Arel сговорились, чтобы остановить вас, поэтому вы вынуждены использовать маршрутируемый маршрут эвакуации и "просто использовать фрагмент строки SQL", и вы получите результат, который не может быть привязан, но остальная часть вашего кода ожидает отношения! (например, постраничные результаты)