我有一个简单的通用模型导轨,如下所示:
class Thing < ApplicationRecord
attribute :foo, :integer
include AConcern
end
它包括一个看起来像这样的基本问题……
module AConcern
extend ActiveSupport::Concern
end
该模型还具有一个名为:foo的属性,使用下面的属性api:
https://api.rubyonrails.org/classes/ActiveRecord/Attributes/ClassMethods.html
属性与关注点相关,因此每次我要使用关注点时,都必须在每个模型中定义属性,然后包含关注点。
如果我将属性declration放在这样的关注点内:
module AConcern
extend ActiveSupport::Concern
attribute :foo, :integer
end
我收到以下错误:
undefined method `attribute' for AConcern:Module
如何在关注中使用属性定义,因此不必在包括关注在内的每个模型中都对其进行声明?谢谢
答案 0 :(得分:2)
您可以使用ActiveSupport::Concern
附带的钩子来处理此问题,例如
module AConcern
extend ActiveSupport::Concern
included do
attribute :foo, :integer
end
end
然后
class Thing < ApplicationRecord
include AConcern
end
您当前遇到的问题是在attribute
的上下文中正在调用Module
,但是该模块无法访问该方法(因此NoMethodError
)。
调用included
时将运行include
钩子,并且该钩子在包含Object
(在这种情况下为Thing
)的上下文中运行。 Thing
确实具有attribute
方法,因此一切正常。
included
中的 ActiveSupport::Concern
块与(在纯红宝石中)基本上相同
module AConcern
def self.included(base)
base.class_eval { attribute :foo, :integer }
end
end