Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 覆盖Rails默认的\u范围_Ruby On Rails - Fatal编程技术网

Ruby on rails 覆盖Rails默认的\u范围

Ruby on rails 覆盖Rails默认的\u范围,ruby-on-rails,Ruby On Rails,如果我有一个带有默认作用域的ActiveRecord::Base模型: class Foo < ActiveRecord::Base default_scope :conditions => ["bar = ?",bar] end 是否有任何方法可以在不使用默认范围条件的情况下执行Foo.find?换句话说,您可以覆盖默认范围吗 我本以为在名称中使用“default”意味着它是可重写的,否则它会被称为类似全局作用域的东西,对吗?简短回答:除非你真的必须使用默认作用域,否则不

如果我有一个带有默认作用域的ActiveRecord::Base模型:

class Foo < ActiveRecord::Base

  default_scope :conditions => ["bar = ?",bar]

end
是否有任何方法可以在不使用默认范围条件的情况下执行Foo.find?换句话说,您可以覆盖默认范围吗

我本以为在名称中使用“default”意味着它是可重写的,否则它会被称为类似全局作用域的东西,对吗?

简短回答:除非你真的必须使用默认作用域,否则不要使用默认作用域。使用命名作用域可能会更好。也就是说,如果需要,可以使用With_EXCLUSIT_作用域覆盖默认作用域


查看更多详细信息。

您可以使用with_EXCLUSIC_scope方法覆盖默认范围。因此:

foos = Foo.with_exclusive_scope { :conditions => ["baz = ?", baz] }
文档 在Rails 3中:

foos = Foo.unscoped.where(:baz => baz)

Rails 3的默认范围似乎不像Rails 2中那样被覆盖

e、 g

在我的应用程序中,使用PostgreSQL,默认范围内的排序获胜。我将删除所有默认的\u作用域,并在任何地方显式地对其进行编码


陷阱栏杆3

如果您只需要更改默认范围中定义的顺序,则可以使用

从4.1开始,您可以使用来对抗默认范围:

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
可以取消作用域,例如::where,:select,:group,:order,:lock,:limit,:offset,:joins,:includes,:from,:readonly,:having


但是,如果可以的话,请避免使用默认范围。这是为了你好。

对于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)

好的,您总是可以在完整查询中使用旧的favorite find_by_sql。 例如:
Model.find_by_sqlSELECT*来自Rails 5.1+或更早版本上id=123的模型,但我已经测试过它在5.1上工作,可以取消特定列的作用域,这是以可在命名作用域内使用的方式删除默认作用域的理想解决方案。在OPs默认范围的情况下


两者都会导致sql查询不应用原始范围,但应用任何其他条件合并到arel中。

这有一个副作用,如果Post有很多注释,Post.first.comments.unscoped会返回所有注释。这确实让我有一段时间搞砸了。特别是如果您最终将其放入一个类方法中,如:def self.random;无范围。命令“兰德”;EndUnscoped删除它之前的所有sql,而不仅仅是默认范围下列出的sql。虽然从技术上讲,这是一个正确的答案,但要小心使用unstoppedWARNING!Unscoped并不只是删除默认的_范围,这已经在另一条评论中说过了,但它确实会把事情搞砸。一个好的经验法则是,只有当它可以直接遵循一个模型时才取消范围,例如Foo.Unscoped.blah是可以的,但决不Foo.blah.Unscoped。解决Enrico提到的副作用,不要使用默认范围,除非你真的必须这样做。一个极好的建议!非常感谢。真的。使用默认范围似乎是个好主意,但在应用程序的生命周期中可能会导致多个问题。先生,您有点夸张了。default\u scope是一个很好的工具,在某些情况下,您可以使用另一种方法,但default\u scope正是正确的选择。例如,当您有一个具有非活动标志的产品模型时,最好设置一个默认的_范围{where inactive:false},因为在99%或更多的情况下,您不希望显示非活动的产品。然后在剩下的1%案例中调用unscoped,这可能是一个管理面板。默认范围违反了最小惊讶原则。我正忙着诅咒以前的开发人员使用它!不是真的,它只是被移动了:看起来它已经被弃用了。你必须使用Bar.foos.reorder:created_at=>:ASC提示:定义一个像scope这样的范围:没有默认顺序,->{reorder},你可以在ASC做Foo.without_default_order.ordercreated_在某些情况下,它读起来更好,也许不是在这个确切的情况下,但我有一个,Reorder帮我做的。谢谢!这对我来说也很有用,将unscoped first Rails称为4.2:User.unscoped.whereemail:foo@example.comThis答案应该更高
SELECT * FROM "foos" ORDER BY created_at asc
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
# 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)
Foo.unscope(where: :bar)
scope :not_default, -> { unscope(where: :bar) }
Foo.not_default