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

时间:2019-04-09 12:59:38

标签: ruby-on-rails attributes ruby-on-rails-5 activesupport-concern

我有一个简单的通用模型导轨,如下所示:

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

如何在关注中使用属性定义,因此不必在包括关注在内的每个模型中都对其进行声明?谢谢

1 个答案:

答案 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