在Ruby中,我有一大堆从数据库返回信息的方法:状态,国家,语言,种族等的列表,用于申请表的选项。我知道从表单中选择的ID,并且正在编写方法来从ID中获取名称:
def state_name(state_id)
Db.states.select{ |s| s['id'] == state_id.to_i }.first['name']
end
def country_name(country_id)
Db.countries.select{ |c| c['id'] == country_id.to_i }.first['name']
end
等。有很多。如何简化1方法,该方法传递项目类型(州,国家等)的名称我想得到名称,而不是一遍又一遍地重复自己?
答案 0 :(得分:3)
您可以通过元编程来解决问题:
class SomeClass
def self.define_name_method(thing, plural)
define_method :"#{thing}_name" do |id|
Db.send(plural).select {|x| x['id'] == id.to_i }.first['name']
end
end
define_name_method :state, :states
define_name_method :country, :countries
end
SomeClass.new.state_name(19749387) #=> "Oregon"
或者使用更通用的方法:
class SomeClass
def thing_name(plural, id)
Db.send(plural).select{|x| x['id'] == id.to_i }.first['name']
end
end
SomeClass.new.thing_name(:countries, 1239394) #=> "Estonia"
答案 1 :(得分:1)
好吧,您可以使用Object#public_send
根据您作为参数传递的“类型名称”调用当前对象上的某个方法:
def name(type, id)
public_send(:"#{type}_name", id)
end
# Call like this:
name(:state, 1)
或者,您可以完全放弃#{type}_name
方法的defenition,只需让您的name
方法调用Db对象上的相应方法:
def name(type, id)
Db.public_send(type).select{ |c| c['id'] == id.to_i }.first['name']
end
# Call like this:
name(:countries, 1)
答案 2 :(得分:0)
使用字符串数组%w(country state)
并使用define_method
和.send
动态创建Db
上的方法和调用属性
%w(country state language).each do |entity|
define_method("#{entity}_name") do |id|
Db.send(entity.pluralize).select{ |o| o['id'] == id.to_i }.first['name']
end
end
(require 'active_support/inflector'
如果不使用R .pluralize
)
动态创建
def state_name(id)
Db.states.select{ |o| o['id'] == id.to_i }.first['name']
end
等country_name
和language_name