如何创建一个在 Rails 5 中没有作用域的作用域?

B S*_*ven 2 activerecord ruby-on-rails scoping ruby-on-rails-5

class Foo < ActiveRecord::Base
  default_scope { where(active: false) }

  scope :include_deleted, -> { unscoped }
Run Code Online (Sandbox Code Playgroud)

这不起作用。它返回范围内的文档。

alias_method :include_deleted, :unscoped
Run Code Online (Sandbox Code Playgroud)

这也不起作用: undefined method 'unscoped'

那么,如何定义一个没有作用域的作用域呢?

用例:是的,我知道我可以只使用unscoped. 让我尝试解释为什么它可能不是一个好主意。有一个很好的理由定义另一个具有相同功能的作用域。原因是它使代码更易于理解,并使我的意图更加明确。unscoped不会告诉读者任何有关默认范围的信息。它只会带来更多的问题。如果我们可以定义另一个作用域来解释我们为什么使用作用域,那么它就会为读者提供上下文并帮助他们理解代码。

顺便说一句,我看到了一些相关的 SO 问题,但它们已经过时了。所以这个问题是关于Rails 5 的。这使它与众不同而不是重复

使用 Mongoid 5,但我认为这不会改变答案。

Boo*_*age 5

为确保清除默认范围,您可以取消where子句的范围,如下所示:

scope :deleted, -> { unscope(where: :active).where(active: false) }
scope :without_deleted, -> { where(active: true) }
scope :with_deleted, -> { unscope(where: :active) }
default_scope { without_deleted }
Run Code Online (Sandbox Code Playgroud)

我更喜欢使用名为deleted_at. 这样我就可以标记删除时间。在这种情况下,范围将如下所示:

scope :deleted, -> { unscope(where: :deleted_at).where.not(deleted_at: nil) }
scope :without_deleted, -> { where(deleted_at: nil) }
scope :with_deleted, -> { unscope(where: :deleted_at) }
default_scope { without_deleted }
Run Code Online (Sandbox Code Playgroud)