Ruby on rails 如何重构已弃用别名\u方法\u链的代码
我正在升级我的rails应用程序,我收到一条警告说,Ruby on rails 如何重构已弃用别名\u方法\u链的代码,ruby-on-rails,ruby,deprecated,Ruby On Rails,Ruby,Deprecated,我正在升级我的rails应用程序,我收到一条警告说,alias\u method\u chain不推荐使用。请改用模块#prepend。但我真的不明白如何处理这件事。如何更改下面的代码 def read_attribute_with_mapping(attr_name) read_attribute_without_mapping(ADDRESS_MAPPING[attr_name] || attr_name) end alias_method_chain :read_att
alias\u method\u chain不推荐使用。请改用模块#prepend
。但我真的不明白如何处理这件事。如何更改下面的代码
def read_attribute_with_mapping(attr_name)
read_attribute_without_mapping(ADDRESS_MAPPING[attr_name] || attr_name)
end
alias_method_chain :read_attribute, :mapping
prepend
基本上类似于导入一个模块,但它最终位于其他代码的“前面”(因此模块可以调用super
来运行它前面的代码)
这是一个与您的情况非常接近的可运行示例
module MyModule
def read_attribute(attr_name)
super("modified_#{attr_name}")
end
end
class Example
prepend MyModule
def read_attribute(attr_name)
puts "Reading #{attr_name}"
end
end
Example.new.read_attribute(:foo)
# Outputs: Reading modified_foo
我直接在示例
上定义了read\u属性
,但它也可以是从超类继承的方法(例如ActiveRecord::Base
)
这是一个更短但更神秘的版本,使用匿名模块:
class Example
prepend(Module.new do
def read_attribute(attr_name)
super("modified_#{attr_name}")
end
end)
def read_attribute(attr_name)
puts "Reading #{attr_name}"
end
end
Example.new.read_attribute(:foo)
# Outputs: Reading modified_foo
更新:
为了好玩并解决下面的一个问题,这里介绍了如何在不必自己明确制作任何模块的情况下完成这项工作。我不认为我会选择这样做,因为它掩盖了一个共同的模式
# You'd do this once somewhere, e.g. config/initializers/prepend_block.rb in a Rails app.
class Module
def prepend_block(&block)
prepend Module.new.tap { |m| m.module_eval(&block) }
end
end
# Now you can do:
class Example
prepend_block do
def read_attribute(attr_name)
super("modified_#{attr_name}")
end
end
def read_attribute(attr_name)
puts "Reading #{attr_name}"
end
end
Example.new.read_attribute(:foo)
# Outputs: Reading modified_foo
如果这只在一个地方使用,我可以将其添加到该类中而不是作为模块吗?不,
prepend
需要一个模块,但它可以是匿名的内联模块,如上面的第二个示例所示。我添加了第三个示例,只是为了取笑如何隐藏该模块,但您很可能不想这样做。在我看来,它节省了很少的打字时间,几乎没有什么胜利。在没有模块的情况下可以实现这一点,就像alias\u method\u chain
所做的那样,但通常坚持Rails的方式更令人愉快,除非你有充分的理由不这样做。