如何在 Rails 中的关注点内使用属性 API?

How to use the Attribute API inside a concern in a Rails?

我有一个简单的通用模型 rails,看起来像这样:

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

属性与关注点相关,所以每次我想使用关注点时,我都必须在每个模型中定义属性然后包含关注点。

如果我像这样将属性声明放在​​关注点中:

module AConcern
  extend ActiveSupport::Concern
  attribute :foo, :integer
end

我收到以下错误:

undefined method `attribute' for AConcern:Module

如何在关注点中使用属性定义,这样我就不必在包含关注点之前在每个模型中声明它?谢谢

您可以使用 ActiveSupport::Concern 包含的钩子来处理这个问题,例如

module AConcern
  extend ActiveSupport::Concern
  included do 
    attribute :foo, :integer
  end
end 

然后

class Thing < ApplicationRecord
  include AConcern
end

您现在遇到的问题是 attributeModule 的上下文中被调用,但该模块无法访问该方法(因此 NoMethodError) .

当您调用 include 时,included 挂钩是 运行,并且在包含 Object 的上下文中挂钩是 运行(Thing 在这种情况下)。 Thing 确实有 attribute 方法,因此一切都按预期工作。

来自 ActiveSupport::Concern

included 块与(纯 ruby)

基本相同
module AConcern
  def self.included(base) 
    base.class_eval { attribute :foo, :integer } 
  end 
end