Last Updated: February 25, 2016
·
2.012K
· rafaelcgo

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 }

3 Responses
Add your response

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.

over 1 year ago ·

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.

over 1 year ago ·

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.

over 1 year ago ·