在活动模型问题中使用常见的 class 常量名称
Using common class constant name in active model concerns
我希望有多个模型具有共同的货币转换实现和一个共同的常量名称——这里是 PRICE_ATTR
module Priceable
extend ActiveSupport::Concern
def value_for(attr, rate)
(self.send(attr) / rate).round(2)
end
PRICE_ATTR.each do |attribute|
method_name = "#{attribute}_currency".to_sym
define_method(method_name) do |rate|
value_for(attribute, rate)
end
end
end
class Design
PRICE_ATTR = [:discount_price, :price]
include Priceable
end
class Cart
PRICE_ATTR = [:snapshot_price]
include Priceable
end
我该怎么做?
您可以像下面这样使用
module Priceable
extend ActiveSupport::Concern
included do
class_variable_set(:@@price_attrs , [])
end
module ClassMethods
def has_prizes(attrs)
class_variable_set(:@@price_attrs, attrs)
end
end
def value_for(attr, rate)
(self.send(attr) / rate).round(2)
end
class_variable_get(:@@price_attrs).each do |attribute|
method_name = "#{attribute}_currency".to_sym
define_method(method_name) do |rate|
value_for(attribute, rate)
end
end
end
class Design
PRICE_ATTR = [:discount_price, :price]
include Priceable
has_prizes PRICE_ATTR
end
class Cart
PRICE_ATTR = [:snapshot_price]
include Priceable
has_prizes PRICE_ATTR
end
或者您可以使用 cattr_accessor 而不是 class_variable_get 和 class_variable_get
这就是 Module#included
的用途!
module Priceable
extend ActiveSupport::Concern
def value_for(attr, rate)
(self.send(attr) / rate).round(2)
end
def self.included(othermod)
othermod::PRICE_ATTR.each do |attribute|
method_name = "#{attribute}_currency".to_sym
othermod.send :define_method, method_name do |rate|
value_for(attribute, rate)
end
end
end
end
class Design
PRICE_ATTR = [:discount_price, :price]
include Priceable
end
class Cart
PRICE_ATTR = [:snapshot_price]
include Priceable
end
当您将 Priceable 包含到另一个模块(作为参数 othermod 传递)时,它会得到 运行。在该模块中,您可以遍历包含模块的 PRICE_ATTR 数组并在其上定义方法。
我希望有多个模型具有共同的货币转换实现和一个共同的常量名称——这里是 PRICE_ATTR
module Priceable
extend ActiveSupport::Concern
def value_for(attr, rate)
(self.send(attr) / rate).round(2)
end
PRICE_ATTR.each do |attribute|
method_name = "#{attribute}_currency".to_sym
define_method(method_name) do |rate|
value_for(attribute, rate)
end
end
end
class Design
PRICE_ATTR = [:discount_price, :price]
include Priceable
end
class Cart
PRICE_ATTR = [:snapshot_price]
include Priceable
end
我该怎么做?
您可以像下面这样使用
module Priceable
extend ActiveSupport::Concern
included do
class_variable_set(:@@price_attrs , [])
end
module ClassMethods
def has_prizes(attrs)
class_variable_set(:@@price_attrs, attrs)
end
end
def value_for(attr, rate)
(self.send(attr) / rate).round(2)
end
class_variable_get(:@@price_attrs).each do |attribute|
method_name = "#{attribute}_currency".to_sym
define_method(method_name) do |rate|
value_for(attribute, rate)
end
end
end
class Design
PRICE_ATTR = [:discount_price, :price]
include Priceable
has_prizes PRICE_ATTR
end
class Cart
PRICE_ATTR = [:snapshot_price]
include Priceable
has_prizes PRICE_ATTR
end
或者您可以使用 cattr_accessor 而不是 class_variable_get 和 class_variable_get
这就是 Module#included
的用途!
module Priceable
extend ActiveSupport::Concern
def value_for(attr, rate)
(self.send(attr) / rate).round(2)
end
def self.included(othermod)
othermod::PRICE_ATTR.each do |attribute|
method_name = "#{attribute}_currency".to_sym
othermod.send :define_method, method_name do |rate|
value_for(attribute, rate)
end
end
end
end
class Design
PRICE_ATTR = [:discount_price, :price]
include Priceable
end
class Cart
PRICE_ATTR = [:snapshot_price]
include Priceable
end
当您将 Priceable 包含到另一个模块(作为参数 othermod 传递)时,它会得到 运行。在该模块中,您可以遍历包含模块的 PRICE_ATTR 数组并在其上定义方法。