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

问题描述 投票:0回答:1

我有一个简单的通用模型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

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

ruby-on-rails attributes ruby-on-rails-5 activesupport-concern
1个回答
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方法,因此一切都按预期工作。

来自includedActiveSupport::Concern块与(纯红宝石)基本相同

module AConcern
  def self.included(base) 
    base.class_eval { attribute :foo, :integer } 
  end 
end
© www.soinside.com 2019 - 2024. All rights reserved.