如果我有一个带默认范围的ActiveRecord :: Base模型:
class Foo < ActiveRecord::Base
  default_scope :conditions => ["bar = ?",bar]
end
有没有办法Foo.find 不使用这些default_scope条件?换句话说,您可以覆盖默认范围吗?
我原以为在名称中使用'default'会表明它是可以覆盖的,否则会被称为类似的global_scope,对吧?
Vin*_*ent 210
在Rails 3中:
foos = Foo.unscoped.where(:baz => baz)
Pär*_*der 149
简短的回答:default_scope除非你真的需要,否则不要使用.使用命名范围可能会更好.话虽如此,with_exclusive_scope如果需要,您可以使用覆盖默认范围.
有关更多详细信息,请查看此问题.
Gui*_*iGS 106
如果您只需要更改定义的顺序default_scope,则可以使用该reorder方法.
class Foo < ActiveRecord::Base
  default_scope order('created_at desc')
end
Foo.reorder('created_at asc')
运行以下SQL:
SELECT * FROM "foos" ORDER BY created_at asc
jib*_*iel 49
既然4.1你可以ActiveRecord::QueryMethods#unscope用来对抗默认范围:
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
这是目前可能unscope的东西一样::where, :select, :group, :order, :lock, :limit, :offset, :joins, :includes, :from, :readonly, :having.
但如果可以,请尽量避免使用default_scope.这是为了你自己的利益.
Joh*_*ley 14
您可以使用该with_exclusive_scope方法覆盖默认范围.所以:
foos = Foo.with_exclusive_scope { :conditions => ["baz = ?", baz] }
在 Rails 5.1+(也许更早,但我已经测试过它适用于 5.1)上,可以取消特定列的范围,恕我直言,这是以default_scope可在命名范围内使用的方式删除 a 的理想解决方案。在 OP 的情况下default_scope,
Foo.unscope(where: :bar)
或者
scope :not_default, -> { unscope(where: :bar) }
Foo.not_default
两者都会导致不应用原始范围的 sql 查询,但会应用合并到 arel 中的任何其他条件。
Rails 3 default_scope似乎没有像在Rails 2中那样被覆盖.
例如
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"
在我的应用程序中,使用PostgreSQL,默认范围WINS中的排序.我正在删除所有的default_scopes并在任何地方显式编码.
陷阱Rails3!
使用Rails 3+,您可以使用unscoped和merge的组合:
# model User has a default scope
query = User.where(email: "foo@example.com")
# get rid of default scope and then merge the conditions
query = query.unscoped.merge(query)
| 归档时间: | 
 | 
| 查看次数: | 82145 次 | 
| 最近记录: |