Rails 3: Scope returns an array

2019-03-04 05:45发布

问题:

I am using a scope to get an Item for a specific user:

In Item model

belongs_to :user    
scope :for_user, lambda { |user| where(:user_id => user) }

User model

has_many :items

Problem

When calling Item.includes(:user).for_user(3) an Array is returned instead of an ActiveRecord relation. I'd expect it to behave like Item.includes(:user).find_by_user_id(3), which returns a ActiveRecord relation.

Thanks for your help.

回答1:

if you do some more investigation you'll find ou that it does indeed return a relation object.

But it will when necessary convert it into an array.

Namely, if you're in a console and say > Item.includes(:user).for_user(3) it will try to inspect it, and consequently do the conversion.

But by all means the following will work

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


回答2:

Using where(:user_id => user) instead of dynamic method like find_by_user_id would always return an array. If you're only interested in the first record returned from your scope you can change your scope to be something like

scope :for_user, lambda { |user| where(:user_id => user).first }