如何在 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
您现在遇到的问题是 attribute
在 Module
的上下文中被调用,但该模块无法访问该方法(因此 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
我有一个简单的通用模型 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
您现在遇到的问题是 attribute
在 Module
的上下文中被调用,但该模块无法访问该方法(因此 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