#ruby-on-rails #activerecord #scope
#ruby-on-rails #activerecord #область
Вопрос:
Я использую область для получения элемента для определенного пользователя:
В модели элемента
belongs_to :user
scope :for_user, lambda { |user| where(:user_id => user) }
Пользовательская модель
has_many :items
Проблема
При вызове Item.includes(:user).for_user(3)
вместо отношения ActiveRecord возвращается массив. Я бы ожидал, что он будет вести себя так Item.includes(:user).find_by_user_id(3)
, что возвращает отношение ActiveRecord .
Спасибо за вашу помощь.
Ответ №1:
если вы проведете еще некоторое исследование, вы обнаружите, что ou действительно возвращает объект отношения.
Но при необходимости он преобразует его в массив.
А именно, если вы находитесь в консоли и говорите > Item.includes(:user).for_user(3)
, что она попытается проверить ее и, следовательно, выполнить преобразование.
Но во что бы то ни стало будет работать следующее
scope = Item.includes(:user).for_user(3)
# does a db count
scope.count
# does a db select limit 1
scope.first
# does a full db select
scope.all
Комментарии:
1. ах .. когда вы говорите «объект отношения ActiveRecord», вы имеете в виду «ActiveRecord» или «отношение ActiveRecord»? Это две разные вещи.
Ответ №2:
Использование where(:user_id => user)
вместо динамического метода, такого как find_by_user_id, всегда будет возвращать массив. Если вас интересует только первая запись, возвращенная из вашей области, вы можете изменить свою область на что-то вроде
scope :for_user, lambda { |user| where(:user_id => user).first }
Комментарии:
1. У меня это не работает. Он выполняет следующее: ВЫБЕРИТЕ
cities
.*cities
ОТКУДАcities
.name
= ‘Berlin’ LIMIT 1 ВЫБЕРИТЕcities
.* ИЗcities
. И в результате получается массив всех.