In Rails 3:
foos = Foo.unscoped.where(:baz => baz)
Short answer: Do not use default_scope
unless you really have to. You'll probably be better off with named scopes. With that said, you can use with_exclusive_scope
to override the default scope if you need to.
Have a look at this question for more details.
If all you need is to change the order defined in default_scope
, you can use the reorder
method.
class Foo < ActiveRecord::Base
default_scope order('created_at desc')
end
Foo.reorder('created_at asc')
runs the following SQL:
SELECT * FROM "foos" ORDER BY created_at asc
Since 4.1
you can use ActiveRecord::QueryMethods#unscope
to fight default scope:
class User < ActiveRecord::Base
default_scope { where tester: false }
scope :testers, -> { unscope(:where).where tester: true }
scope :with_testers, -> { unscope(:where).where tester: [true, false] }
# ...
end
It is currently possible to unscope
stuff like: :where, :select, :group, :order, :lock, :limit, :offset, :joins, :includes, :from, :readonly, :having
.
But still please avoid using of default_scope
if you can. It's for your own good.
You can override a default scope using the with_exclusive_scope
method. So:
foos = Foo.with_exclusive_scope { :conditions => ["baz = ?", baz] }
with_exclusive_scope
documentationOn Rails 5.1+ (and maybe earlier, but I've tested it works on 5.1) it is possible to unscope a specific column, which imho is the ideal solution for removing a default_scope
in a fashion that can be used inside a named scope. In the case of the OPs default_scope
,
Foo.unscope(where: :bar)
Or
scope :not_default, -> { unscope(where: :bar) }
Foo.not_default
Will both result in a sql query that doesn't apply the original scope, but does apply whatever other conditions get merged into the arel.
Rails 3 default_scope does not appear to get overridden like it did in Rails 2.
e.g.
class Foo < ActiveRecord::Base
belongs_to :bar
default_scope :order=>"created_at desc"
end
class Bar < ActiveRecord::Base
has_many :foos
end
> Bar.foos
SELECT * from Foo where bar_id = 2 order by "created_at desc";
> Bar.unscoped.foos
SELECT * from Foo; (WRONG! removes the "has" relationship)
> Bar.foos( :order=>"created_at asc" ) # trying to override ordering
SELECT * from Foo where bar_id = 2 order by "created_at desc, created_at asc"
In my app, using PostgreSQL, the ordering in the default scope WINS. I'm removing all of my default_scopes and coding it in explicitly everywhere.
Pitfall Rails3!
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