我在Rails中定义自己的AR类,其中包括为用户字段0-9动态创建的实例方法。用户字段不直接存储在数据库中,它们将被序列化在一起,因为它们不经常使用。以下是最好的方法吗?替代?
从哪里调用添加方法的启动代码?
class Info < ActiveRecord::Base
end
# called from an init file to add the instance methods
parts = []
(0..9).each do |i|
parts.push "def user_field_#{i}" # def user_field_0
parts.push "get_user_fields && @user_fields[#{i}]"
parts.push "end"
end
Info.class_eval parts.join
答案 0 :(得分:10)
一种不错的方法,特别是如果您的用户字段数超过0..9,则可以使用method_missing
:
class Info
USER_FIELD_METHOD = /^user_field_(\n+)$/
def method_missing(method, *arg)
return super unless method =~ USER_FIELD_METHOD
i = Regexp.last_match[1].to_i
get_user_fields && @user_fields[i]
end
# Useful in 1.9.2, or with backports gem:
def respond_to_missing?(method, private)
super || method =~ USER_FIELD_METHOD
end
end
如果您更喜欢定义方法:
10.times do |i|
Info.class_eval do
define_method :"user_field_#{i}" do
get_user_fields && @user_fields[i]
end
end
end
答案 1 :(得分:4)
使用method_missing
非常难以维护和不必要。使用define_method
的另一种方法更好,但会导致代码效果不佳。您只需要以下1个衬垫:
class Info
end
Info.class_eval 10.times.inject("") {|s,i| s += <<END}
def user_field_#{i}
puts "in user_field_#{i}"
end
END
puts Info.new.user_field_4