简体   繁体   English

如何在Rails中关注的内部使用Attribute API?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM