将ActiveSupport :: Concern模块与vanilla模块混合是危险的吗?

时间:2017-03-31 08:47:53

标签: ruby ruby-on-rails-5 activesupport activesupport-concern

我知道隐藏在ActiveSupport::Concern后面的依赖管理系统。我完全不明白(我不确定我还没准备好),但简而言之:是否可以将ActiveSupport::Concern与香草(非ActiveSupport::Concern)模块混合,或者有陷阱吗?

以下是我能想到的不同用法的一些例子

module Vanilla
  module ModuleIncludedInASC
    # Vanilla module
  end

  module ModuleIncludedInClass
    # Vanilla module
  end

module ASC
  module ConcernIncludedInClass
    extend ActiveSupport::Concern
    ...
  end

  module ConcernIncludedInASC
    extend ActiveSupport::Concern
    ...
  end

  module ConcernIncludingVanillaModulesIncludedInClass
    extend ActiveSupport::Concern
    include Vanilla::VanillaConcernIncludedInASC
  end
  module ConcernIncludingASCConcernIncludedInASC
    extend ActiveSupport::Concern
    include ConcernIncludedInASC
  end
end

class MyFoo
  include Vanilla::ModuleIncludedInClass
  include ASC::ConcernIncludedInClass
  include ASC::ConcernIncludingVanillaModulesIncludedInClass
end

# Ans also possibly, ActiveSupport::Concern modules included in vanilla modules...?

这可能会导致问题吗?

2 个答案:

答案 0 :(得分:1)

这应该不是问题。

我不能谈论深刻的技术细节,但我从未见过有人提到它有风险,而且我一直这样做。我有一些10 + includes的模型。其中一些模块正在使用ActiveSupport::Concern,有些则不是。从未遇到任何问题。

我建议尝试并发布一个新问题,如果它确实会导致问题。

答案 1 :(得分:1)

我还没有遇到任何问题,但是理论上存在潜在的问题。

如果在类中包含该模块,则在正常模块中定义的方法附加到方法查找链。因此,类中定义的方法将覆盖普通模块中的方法。

在关注点的included块中定义的方法将直接添加到包含关注点的类中。

结果是,即使您在正常模块之前包含关注点,关注中的方法也将始终覆盖正常模块中的方法。

实施例

module Normal
  def foo
    'normal'
  end
end

module Concern
  extend ActiveSupport::Concern
  included do
    def foo
      'concern'
    end
  end
end

class Bar
  include Concern  # include concern first
  include Normal   # then include normal
end

Bar.new.foo  #=> "concern"

也许你会期望"normal"被退回,但这永远不会发生。