[英]How to use the Attribute API inside a concern in a Rails?
I have a simple generic model rails that looks like this: 我有一个简单的通用模型导轨,如下所示:
class Thing < ApplicationRecord
attribute :foo, :integer
include AConcern
end
And it include a basic concern that looks like this… 它包括一个看起来像这样的基本问题...
module AConcern
extend ActiveSupport::Concern
end
The model also has an attribute called :foo using the attribute api from below: 该模型还有一个名为:foo的属性,使用下面的属性api:
https://api.rubyonrails.org/classes/ActiveRecord/Attributes/ClassMethods.html https://api.rubyonrails.org/classes/ActiveRecord/Attributes/ClassMethods.html
The attribute relates to the the concern, so every time I want to use the concern, in each model I have to define the attribute and then include the concern. 属性与关注有关,因此每次我要使用关注时,在每个模型中我都必须定义属性,然后包括关注。
If I put the attribute declration inside the concern like this: 如果我将属性斜率放在这样的关注点内:
module AConcern
extend ActiveSupport::Concern
attribute :foo, :integer
end
I get the following error: 我收到以下错误:
undefined method `attribute' for AConcern:Module
How do I use the attribute definition in the concern so I don't have to declare it in every model before including the concern? 如何在关注中使用属性定义,这样在包含关注时不必在每个模型中都声明它? Thanks 谢谢
You can use ActiveSupport::Concern
included hook to handle this eg 您可以使用ActiveSupport::Concern
包含的钩子来处理此问题,例如
module AConcern
extend ActiveSupport::Concern
included do
attribute :foo, :integer
end
end
Then 然后
class Thing < ApplicationRecord
include AConcern
end
The problem you are experiencing right now is that attribute
is being called in the context of your Module
but that module does not have access to that method (hence NoMethodError
). 您现在遇到的问题是在Module
的上下文中调用了attribute
,但是该模块无权访问该方法(因此NoMethodError
)。
The included
hook is run when you call include
and the hook is run in the context of the including Object
( Thing
in this case). 当您调用include
时, included
挂钩运行,并且该挂钩在包含Object
的上下文中运行(在这种情况下为Thing
)。 Thing
does have the attribute
method and thus everything works as expected. Thing
确实具有attribute
方法,因此一切都按预期工作。
included
block from ActiveSupport::Concern
is essentially the same as (in pure ruby) ActiveSupport::Concern
included
块基本上与(在纯红宝石中)相同
module AConcern
def self.included(base)
base.class_eval { attribute :foo, :integer }
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.