【发布时间】:2013-07-13 02:36:53
【问题描述】:
我正在尝试使用 RailsCast #345 (Hstore) 中的元编程示例代码,并将静态数组替换为从应用程序中的另一个(不相关)模型生成的数组。 Ryan 的代码示例是:
class Product < ActiveRecord::Base
attr_accessible :name, :category, :price, :description
# store_accessor :properties, :author
%w[author rating runtime].each do |key|
attr_accessible key
define_method(key) do
properties && properties[key]
end
define_method("#{key}=") do |value|
self.properties = (properties || {}).merge(key => value)
end
end
end
我想用Foo.pluck(:content).map(&:downcase) 之类的东西替换上面的%w[author rating runtime],但这不起作用。尝试访问动态方法时出现方法未定义错误。例如调用时
@product.send(foo.content.downcase) # <-- which returns "author"
我明白了:
undefined method `author' for #<Product:0x007ff111df0908>
使用静态数组可以正常工作。
是否可以替换该静态数组?我想从管理员填充的另一个模型中读取这些值,而不必接触新值的代码。也可以使用其他方法来完成同样的事情!感谢您的宝贵时间。
【问题讨论】:
-
所以您的
Foo.pluck(:content).map(&:downcase)在控制台中尝试时会产生预期的输出,但在加载Product类时执行时什么也不产生?总是有method_missing作为备份。 -
是的。它在控制台中生成正确的数组,但 Product.send(..) 除非数组是硬编码的,否则它不起作用。我会看看 method_missing 但我认为它应该是最后的手段(或如你所说的备份)。谢谢
-
你得到什么具体的错误报告?您是否尝试过要求包含 Foo 的文件?
-
更新了这个问题,我只有在数组没有硬编码时才会得到错误。我尝试在 Product 类中添加 require 'foo' 并且得到了相同的结果。谢谢。
-
我猜当 Ruby 加载你的
Product类时没有可用的数据库:没有数据库意味着没有Foos 意味着没有创建方法。 AFAIK,ActiveRecord 在第一次调用method_missing时使用method_missing生成属性方法。
标签: ruby-on-rails metaprogramming railscasts class-method