Возможно ли получить объект ActiveRecord:: Relation для ассоциации
-
Используются ли методы ассоциации, такие как те, которые определены has_many
и belongs_to
, ActiveRecord::Relation
?
-
Если да, возможно ли получить объект ActiveRecord::Relation
, который используется.
Мы все знаем, что Rails 3 сильно использует объекты ActiveRecord::Relation
и Arel::Relation
объекты в фоновом режиме при создании запросов с помощью Query Interface. Всякий раз, когда мы используем методы select
, joins
и т.д. Интерфейса запросов, возвращается объект ActiveRecord::Relation
. Однако это не похоже на вызов метода ассоциации модели. Вместо этого запрос выполняется немедленно, и возвращается экземпляр или массив экземпляров связанной модели.
Рассмотрим следующие модели:
post.rb
class Post < ActiveRecord::Base
belongs_to :user
end
user.rb
class user < ActiveRecord::Base
has_many :posts
end
Пример:
u = User.first
u.posts
Вызов u.posts
возвращает массив сообщений, а не экземпляр ActiveRecord::Relation
. Мне интересно, можно ли получить ActiveRecord::Relation
, который используется ассоциацией, если он вообще используется, возможно, используя Arel::Table
?
Мое рассуждение о желании ActiveRecord::Relation
должно быть очевидным: это потому, что я хочу связать существующую ассоциацию и манипулировать запросом в соответствии с другой целью.
Ответы
Ответ 1
В течение нескольких минут я использовал where(nil)
hack, тогда у меня была мозговая волна и пробовал что-то случайное:
User.first.posts.scoped
Что это!: D
Да, Rails + Arel действительно плохо документирован. С нетерпением ждем его созревания до такой степени, что я действительно смогу посмотреть вещи и получить ответы на реальные вопросы.
Ответ 2
в Rails 4 используйте .scope
или .spawn
для доступа к объекту отношения вместо CollectionProxy
. См. документация.
Ответ 3
Пользуясь временем, чтобы действительно прочитать документацию Edge Guides, я смог найти ответ в Раздел 4.3 has_many
Ссылка на ассоциацию. Короче говоря, документация не проливает свет на то, можно ли получить объект ActiveRecord::Relation
или использовать объект ActiveRecord::Relation
, но он подробно описывает, как повторно использовать связь и адаптировать ее результат.
Раздел 4.3.1 Методы, добавленные has_many
, перечисляют collection
.where
как один из методов, который добавляется has_many
. Раздел 4.3.1.11 collection
.where(…)
показывает, что вы будете использовать его так же, как и пользовательский метод where
интерфейса запроса, Что еще более важно, он дает подсказку, что объекты лениво загружаются при использовании этого метода в коллекции, и, конечно же, возвращается объект ActiveRecord::Relation
.
u.posts.where("").class # => ActiveRecord::Relation
u.posts.where("").to_sql # => SELECT `posts`.* FROM `posts` WHERE `posts`.user_id = 1
По общему признанию, это не идеальное решение, но оно дает мне то, от чего я могу соединиться.
Ответ 4
В ActiveSupport::Concern
вы не можете вызвать частный метод spawn
или использовать scope
или scoped
.
Мне нужно было это использовать.
where(true)