Rails 3: Область возвращает массив

#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 . И в результате получается массив всех.