Starting Rails 4, Model.scoped is now deprecated.
DEPRECATION WARNING: Model.scoped is deprecated. Please use Model.all instead.
But, there's a difference inModel.scoped and Model.all, that is, scoped.scoped returns a scope, while all.all runs the query.
On Rails 3:
> Model.scoped.scoped.is_a?(ActiveRecord::Relation)
=> true
On Rails 4:
> Model.all.all.is_a?(ActiveRecord::Relation)
DEPRECATION WARNING: Relation#all is deprecated. If you want to eager-load a relation, you can call #load (e.g. `Post.where(published: true).load`). If you want to get an array of records from a relation, you can call #to_a (e.g. `Post.where(published: true).to_a`).
=> false
There are use cases in libraries / concerns that returns scoped when there's a conditional to do something or nothing, like so:
module AmongConcern
extend ActiveSupport::Concern
module ClassMethods
def among(ids)
return scoped if ids.blank?
where(id: ids)
end
end
end
If you'd change this scoped to all, you'd face random problems depending where the among was used in the scope chain. For instance, Model.where(some: value).among(ids) would run the query instead of returning a scope.
What I want is an idempotent method on ActiveRecord::Relation that simply returns a scope.
What should I do here?
It seems that where(nil) is a real replacement of scoped, which works both on Rails 3 and 4. :(
On Rails 4.1 (beta 1), the following works:
Model.all.all.is_a?(ActiveRecord::Relation)
=> true
So it appears this issue has been fixed, and in 4.1.0 Model.scoped has been removed altogether.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With