ActiveSupport::Concern 模块是 Ruby 中很常用,且很重要的一个模块。它鼓励抽取可重用逻辑放到不同的concern里面,规范了 module mix 的代码风格,并且解决了模块加载之间的依赖问题。
鼓励公用逻辑抽取,规范代码风格
例如我们有 Post 和 Advertiser 两个类,这两个类拥有相同的判断是否是活跃状态的代码逻辑,scop、实例方法、类方法:
scope :active, -> {where(is_active: true)}
def active?
is_active
end
def self.all_active(reload = false)
@all_active = nil if reload
@all_active ||= active.all
end
为了重用这部分代码,我们将其抽取出来,放到一个module 中,如下:
module ActAsActivable
def self.included(base)
base.send(:include, InstanceMethods)
base.extend ClassMethods
base.class_eval do
scope :active, where(is_active: true)
end
end
module InstanceMethods
def active?
is_active
end
end
module ClassMethods
def all_active(reload = false)
@all_active = nil if reload
@all_active ||= active.all
end
end
end
在 ActAsActivable model 中,为了使该module被 include 时可以为类添加这几个方法,我们将scope 实例方法和类方法写入module中,并分别用 InstanceMethods和ClassMethods包裹,并利用 hook 方法在被 include 的时候为新类添加新方法。
注意:
- 对于实例方法,我们完全可以不用InstanceMethods模块来包裹,当它们被 include 的或者 extend 的时候,它们会自动成为新类的实例方法或类方法。
- 而类方法无论如何定义,都无法自动成为新类的类方法,看下面几个例子:module A def self.test_a end end class

ActiveSupport::Concern是Ruby中用于模块化代码和解决依赖问题的重要工具。它鼓励将可重用逻辑抽离到单独的concerns中,简化模块包含的代码风格。Concern解决了在模块之间依赖的问题,避免了直接include导致的错误。其内部原理涉及append_features和included方法的重写,确保类方法和实例方法的正确添加。通过使用Concern,可以更优雅地管理和组织代码。
最低0.47元/天 解锁文章
492

被折叠的 条评论
为什么被折叠?



