我想为find_by功能创建一堆方法。我不想一遍又一遍地写同样的东西所以我想使用元编程。
假设我想创建一个按名称查找的方法,接受名称作为参数。我该怎么办?我以前使用过define_method但是我没有任何关于该方法的参数。 这是我的(坏)方法
["name", "brand"].each do |attribute|
define_method("self.find_by_#{attribute}") do |attr_|
all.each do |prod|
return prod if prod.attr_ == attr_
end
end
end
有什么想法?提前谢谢。
答案 0 :(得分:37)
如果我理解你的问题,你需要这样的东西:
class Product
class << self
[:name, :brand].each do |attribute|
define_method :"find_by_#{attribute}" do |value|
all.find {|prod| prod.public_send(attribute) == value }
end
end
end
end
(我假设all
方法返回一个Enumerable。)
上述内容或多或少等同于定义两个类方法:
class Product
def self.find_by_name(value)
all.find {|prod| prod.name == value }
end
def self.find_by_brand(value)
all.find {|prod| prod.brand == value }
end
end
答案 1 :(得分:5)
如果你阅读这里的例子http://apidock.com/ruby/Module/define_method,你会发现这个:
define_method(:my_method) do |foo, bar| # or even |*args|
# do something
end
与
相同def my_method(foo, bar)
# do something
end
答案 2 :(得分:1)
执行此操作时:define_method("self.find_by_#{attribute}")
这是不正确的。 define_method的参数是一个带有单个单词的符号。
让我告诉你一些正确的代码,希望这一点很清楚:
class MyClass < ActiveRecord::Base
["name", "brand"].each do |attribute|
define_method(:"find_by_#{attribute}") do |attr_|
first(attribute.to_sym => attr_)
end
end
end
这将为find_by_brand
和find_by_name
生成类方法。
请注意,如果您正在研究元编程,这是method_missing的一个很好的用例。 here's a tutorial使用method_missing实现您想要的相同功能(find_by_<x>
)