Rails:如何从包含的关注点覆盖或私有化给定范围?

阿罗纳

我有一个担心,增加了一个scopeActiveRecord包含它的类。大多数时候它的方式很好,但根据课程的不同,可能需要满足额外的标准。我不想在模型中重写范围,但能够添加一个额外的标准方法。

这是我想要做的:

module MyConcern
  extend ActiveSupport::Concern

  included do
    # I've included the fact I pass a limit variable here because my scope also does this, in case that's relevant for solving this.
    # I'd like this to be private or not accessible via `MyModel._my_scope`
    scope :_my_scope, ->(limit = nil) { (joins, wheres, order etc etc).limit(limit) }
    scope :my_scope, ->(limit = nil) { _my_scope(limit) }
  end
end

class MyModel < ApplicationRecord
  include MyConcern

  # Including the "private" scope to add my extra criteria.
  scope :my_scope, ->(limit = nil) { _my_scope(limit).where(foo: 'bar') }
end

class AnotherModel < ApplicationRecord
  include MyConcern

  # I like the default behavior here so nothing else to do
end

这有效,但在课堂外你可以这样做:MyModel._my_scope我想这没问题 - 也许有一段时间我想要默认行为 - 但在这种情况下,我不认为我这样做,我觉得封装_my_scope是要走的路.

我假设有可能在MyConcern其中包含一个私有类方法,MyModel但这似乎不起作用,而且我还不是一个真正的Concern/mixin 大师,所以不确定如何去做。另外,是否被Concerns认为是mixin?有区别吗?知道这一点也很好。

您可以使用类方法实现作用域的相同功能,您可以在这种情况下继承和扩展。它与您的实现没有太大不同;只是通过使用类方法而不是范围来避免使用额外的 _ 方法。例如

module MyConcern
  extend ActiveSupport::Concern

  class_methods do
    def my_scope(limit = nil)
      (joins, wheres, order etc etc).limit(limit)
    end
  end
end

class MyModel < ApplicationRecord
  include MyConcern

  def self.my_scope(limit = nil)
    super.where(foo: 'bar')
  end
end

class AnotherModel < ApplicationRecord
  include MyConcern
end

对于您问题的第二部分:从技术上讲,关注点是 ruby​​ Mixin;这只是组织/分组模型中包含的 Mixin 仅作为关注点的约定。使用 ActiveSupport::Concern 允许您向 Mixin 添加额外的与模型相关的功能,如范围、验证等,这是使用普通模块无法获得的。例如你不能做

module MyConcern
  scope :my_scope, ->(limit = nil) { _my_scope(limit) }
end

class MyModel < ApplicationRecord
  include MyConcern # this will raise an error
end

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章