如何创建一个在 Rails 5 中没有作用域的作用域?
How to create a scope that is unscoped in Rails 5?
class Foo < ActiveRecord::Base
default_scope { where(active: false) }
scope :include_deleted, -> { unscoped }
这不起作用。它 returns 范围文档。
alias_method :include_deleted, :unscoped
这也不行:undefined method 'unscoped'
那么,如何定义一个没有作用域的作用域?
用例:是的,我知道我可以使用 unscoped
。让我试着解释一下为什么它可能不是一个好主意。有充分的理由定义另一个具有相同功能的范围。原因是它使代码更易于理解,并且使我的意图更加明确。 unscoped
不会告诉 reader 任何有关默认范围的信息。它只会带来更多问题。如果我们可以定义另一个范围来解释 为什么我们使用范围 ,那么它会为 reader 提供上下文并帮助他们理解代码。
顺便说一句,我看到了一些相关的 SO 问题,但它们已经过时了。所以这道题是关于Rails5。这使得它与众不同,不是重复的。
使用 Mongoid 5,但我认为这不会改变答案。
您可以使用 ActiveRecord::QueryMethods#unscope
:
scope :include_deleted, -> { unscope(:where) }
P.S。首先使用 default_scope
通常不是一个好主意。但是关于它的文章太多了,我就不在这里推理了。
为确保清除默认范围,您可以取消 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 }
我更喜欢使用名为 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 }
class Foo < ActiveRecord::Base
default_scope { where(active: false) }
scope :include_deleted, -> { unscoped }
这不起作用。它 returns 范围文档。
alias_method :include_deleted, :unscoped
这也不行:undefined method 'unscoped'
那么,如何定义一个没有作用域的作用域?
用例:是的,我知道我可以使用 unscoped
。让我试着解释一下为什么它可能不是一个好主意。有充分的理由定义另一个具有相同功能的范围。原因是它使代码更易于理解,并且使我的意图更加明确。 unscoped
不会告诉 reader 任何有关默认范围的信息。它只会带来更多问题。如果我们可以定义另一个范围来解释 为什么我们使用范围 ,那么它会为 reader 提供上下文并帮助他们理解代码。
顺便说一句,我看到了一些相关的 SO 问题,但它们已经过时了。所以这道题是关于Rails5。这使得它与众不同,不是重复的。
使用 Mongoid 5,但我认为这不会改变答案。
您可以使用 ActiveRecord::QueryMethods#unscope
:
scope :include_deleted, -> { unscope(:where) }
P.S。首先使用 default_scope
通常不是一个好主意。但是关于它的文章太多了,我就不在这里推理了。
为确保清除默认范围,您可以取消 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 }
我更喜欢使用名为 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 }