0

我知道背后隐藏着一个依赖管理系统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...?

这可能会导致问题吗?

4

2 回答 2

1

这不应该是一个问题。

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

如果确实引起问题,我建议尝试并发布一个新问题。

于 2017-03-31T08:59:09.067 回答
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"被退回,但这永远不会发生。

于 2017-03-31T09:05:25.297 回答