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

Min*_*ure 2 attributes ruby-on-rails activesupport-concern ruby-on-rails-5

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

\n\n
class Thing < ApplicationRecord\n  attribute :foo, :integer\n  include AConcern\nend\n
Run Code Online (Sandbox Code Playgroud)\n\n

它包括一个基本问题,如下所示\xe2\x80\xa6

\n\n
module AConcern\n  extend ActiveSupport::Concern\nend\n
Run Code Online (Sandbox Code Playgroud)\n\n

该模型还有一个名为 :foo 的属性,使用下面的属性 api:

\n\n

https://api.rubyonrails.org/classes/ActiveRecord/Attributes/ClassMethods.html

\n\n

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

\n\n

如果我将属性声明放入关注点中,如下所示:

\n\n
module AConcern\n  extend ActiveSupport::Concern\n  attribute :foo, :integer\nend\n
Run Code Online (Sandbox Code Playgroud)\n\n

我收到以下错误:

\n\n
undefined method `attribute\' for AConcern:Module\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n

eng*_*nky 5

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

module AConcern
  extend ActiveSupport::Concern
  included do 
    attribute :foo, :integer
  end
end 
Run Code Online (Sandbox Code Playgroud)

然后

class Thing < ApplicationRecord
  include AConcern
end
Run Code Online (Sandbox Code Playgroud)

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

included当您调用时,钩子就会运行,include并且钩子在包含的上下文中运行ObjectThing在本例中)。Thing确实有attribute方法,因此一切都按预期进行。

includedblock fromActiveSupport::Concern本质上与(在纯红宝石中)相同

module AConcern
  def self.included(base) 
    base.class_eval { attribute :foo, :integer } 
  end 
end
Run Code Online (Sandbox Code Playgroud)