redirect_to, array and the splat operator
I was wondering if there were a way to make this controller code more readable:
events_controller.rb
format.zip do
if @event.zip_cache_up_to_date?
return [@event.photo_zip.file.url]
else
Resque.enqueue(PhotoZipper, @event.id, @event.class.to_s, current_user.id)
return [events_url, notice: I18n.t('flash.photo_zip.create')]
end
end
I decided to make a private method on the controller that will decide which path redirect_to
should take, but it wasn't working, because redirect_to
params need to be separated by comma.
Exception
NoMethodError in EventsController#show
undefined method `model_name' for Hash:Class
Code
format.zip { redirect_to zip_download_path }
private
def zip_download_path
if @event.zip_cache_up_to_date?
return [@event.photo_zip.file.url]
else
Resque.enqueue(PhotoZipper, @event.id, @event.class.to_s, current_user.id)
return [events_url, notice: I18n.t('flash.photo_zip.create')]
end
end
Then I found out about the *
, the splat operator (http://theplana.wordpress.com/2007/03/03/ruby-idioms-the-splat-operator/). Now it works!
Correction
format.zip { redirect_to *zip_download_path }
Written by Rafael Oliveira
Related protips
3 Responses
You can simplify this further by having your notice called beforehand.
flash[:notice] = ...
You can then return only the urls and therefore remove the arrays, the splat, and the "return" keyword while you are at it.
Hum..... Nice @sunfox! Does flash works like a session storage?
Is it bad to use the 'return' keyword? I always use it, since I think it makes the code more readable.
Exactly! Using notice:
on redirects is actually a shortcut to flash[:notice]
.
I only use the return keyword when I need to explicitly stop a method but it's a question of Ruby-style I guess.