我当前的sinatra路由器看起来像这样但是多个商店正在路上,所以我想用一行代替这个案例,
get_or_post "/list.json" do
case
when params[:store]=='storeVakanties' then return jsonp(get_data_for(Vakantie))
when params[:store]=='storeDeelnemers' then return jsonp(get_data_for(Deelnemer))
when params[:store]=='storeJobstudenten' then return jsonp(get_data_for(Jobstudent))
end
end
如果我将我的ExtJs商店重命名为activerecord类的名称,我可以做类似的事情
get_or_post "/list.json" do
jsonp(get_data_for(params[:store])) #eg params[:store]='Vakantie'
end
但我需要传递一个类,而不是一个字符串..任何建议?
答案 0 :(得分:2)
在最简单的情况下(没有命名空间),您可以使用:
Object.const_get(params[:store])
如果你需要使命名空间不变,你可以做
params[:store].split('::').inject(Object) {|klass, name| klass.const_get(name) }
要获得更高级的实现,请查看ActiveSupport的Inflector constantize
方法的来源:http://apidock.com/rails/v4.0.2/ActiveSupport/Inflector/constantize
答案 1 :(得分:1)
如果你想限制可用的类,这样的东西可以工作:
params = { store: "Vakantie" }
[Vakantie, Deelnemer, Jobstudent].find { |c| c.to_s == params[:store] }
#=> Vakantie
我可能只是编写一个帮助器方法并明确映射这些类:
helpers do
def store(name)
case name
when 'storeVakanties' then Vakantie
when 'storeDeelnemers' then Deelnemer
when 'storeJobstudenten' then Jobstudent
end
end
end
get_or_post "/list.json" do
jsonp(get_data_for(store(params[:store])))
end
答案 2 :(得分:0)
您可以使用eval
:
get_or_post "/list.json" do
jsonp(get_data_for(eval(params[:store])))
end
如果您对此感到震惊,可以使用const_get
:
Kernel.const_get(params[:store])
但是,您需要执行一些验证,因为允许用户输入选择任何已定义的类是危险的。
答案 3 :(得分:0)
我自己使用ActiveSupport的constantize
找到了解决方案jsonp(get_data_for(params[:store].constantize))
在我的情况下,安全性不是问题,但我最喜欢Stefan的解决方案,所以我给了他信用。