在模块前面加上 ActiveSupport::Concern ?红宝石 2+
Posted
技术标签:
【中文标题】在模块前面加上 ActiveSupport::Concern ?红宝石 2+【英文标题】:prepend module with ActiveSupport::Concern ? ruby 2+ 【发布时间】:2018-10-07 07:07:04 【问题描述】:Module Baz
def foo
super
:baz
end
end
Class A
prepend Baz
def foo
:bar
end
end
A.new.foo //works fine
现在,如果我将我的模块转换为关注模块,那不是...
module BazConcern
extend ActiveSupport::Concern
included do
def foo
super
:baz
end
end
end
那么 我们如何在 ActiveSupport::Concern 中使用 prepend ? 在 ruby 2+ 中使用
【问题讨论】:
因为不是inlcuded
,而是prepended
,这是两个不同的钩子。 ActiveSupport::Concern
似乎没有使用它公开included
的块语法公开prepended
。
如果我只是替换为前置 => ArgumentError: wrong number of arguments (given 0, expected 1)
正如我之前的评论中提到的 “ActiveSupport::Concern 似乎没有在其公开的块语法之前公开。” 我觉得可能的原因是这是因为前置模块脱离了ActiveSupport::Concern
的目的。这样做的设计模式似乎是为了更好地组织代码并远离“胖模型”概念,即使该步骤比文字更具形象性。
A Concern 旨在允许支持单一职责主体但随后包含在类中的模块,本质上使它们成为超类(它们被注入模型上方的继承链中)。然而,前置实际上通过取消移位将模块本身置于继承链中,并且所有内容都将首先通过它(通常使用super
调用)。如果您希望您的方法 foo
执行相同的操作,请从关注点中删除 super
,将关注点包含在您的模型中并在 A#foo 中的 :bar 之后添加 super
调用
【参考方案1】:
prepend
和 ActiveSupport::Concern
(Rails 6.1+)
Rails 6.1 添加了对prepend
和ActiveSupport::Concern
的支持。
请看下面的例子:
module Imposter
extend ActiveSupport::Concern
# Same as `included`, except only run when prepended.
prepended do
end
end
class Person
prepend Imposter
end
另外值得一提的是concerning
也更新了:
class Person
concerning :Imposter, prepend: true do
end
end
来源:
对应commit的链接。
Rails allows a module with extend ActiveSupport::Concern to be prepended.
prepend 和 concerning 文档。
【讨论】:
【参考方案2】:似乎有一个支持前置的ActiveSupport::Concern
版本:https://gist.github.com/bcardarella/5735987。
我还没有尝试过,但我可能有一天会尝试。
(链接至https://groups.google.com/forum/#!topic/rubyonrails-core/sSk9IEW74Ro)
【讨论】:
以上是关于在模块前面加上 ActiveSupport::Concern ?红宝石 2+的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Google 在前面加上 while(1);到他们的 JSON 响应?