我有一个担心,增加了一个scope
到ActiveRecord
包含它的类。大多数时候它的方式很好,但根据课程的不同,可能需要满足额外的标准。我不想在模型中重写范围,但能够添加一个额外的标准方法。
这是我想要做的:
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] 删除。
我来说两句