Reputation: 42207
My current sinatra router looks like this but multiple stores are on the way so i would like to replace this case with one line,
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
if i rename my ExtJs store to the name of the activerecord class i could do something like
get_or_post "/list.json" do
jsonp(get_data_for(params[:store])) #eg params[:store]='Vakantie'
end
but i need to pass a class, not a string.. any suggestions ?
Upvotes: 1
Views: 831
Reputation: 114268
If you want to restrict the available classes, something like this would work:
params = { store: "Vakantie" }
[Vakantie, Deelnemer, Jobstudent].find { |c| c.to_s == params[:store] }
#=> Vakantie
I would probably just write a helper method and map the classes explicitly:
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
Upvotes: 1
Reputation: 42207
I found a solution myself using ActiveSupport's constantize
jsonp(get_data_for(params[:store].constantize))
In my case security isn't an issue but i like the solution from Stefan the best so i give him the credits.
Upvotes: 0
Reputation: 44725
In the simplest case (no namespaces) you can use:
Object.const_get(params[:store])
If you need to get namespaced constant, you can do
params[:store].split('::').inject(Object) {|klass, name| klass.const_get(name) }
For more advanced implementation have a look at the source of constantize
method from ActiveSupport's Inflector: http://apidock.com/rails/v4.0.2/ActiveSupport/Inflector/constantize
Upvotes: 2
Reputation: 6397
You could use eval
:
get_or_post "/list.json" do
jsonp(get_data_for(eval(params[:store])))
end
If you’re horrified by that, you could use const_get
:
Kernel.const_get(params[:store])
You’ll need to perform some validation, though, because it’s dangerous to allow user input to select any defined class.
Upvotes: 0