views:

785

answers:

4

I have a controller with multiple actions that take :year and :month as attributes from the URL. I have made a private method check_date to check the date is valid and check the date is not in the future.

def check_date(year, month)
  if month < 1 || month > 12 || year < 2000
    flash[:notice] = I18n.t 'archive.invalid_date'
    redirect_to :action => 'index'
  elsif year > Date.today.year || (year == Date.today.year && month > Date.today.month)
    flash[:notice] = I18n.t 'archive.no_future'
    redirect_to :action => 'month_index', 
      :year => Date.today.year, 
      :month => Date.today.month,
      :type => params[:type]
  end
end

Is there a rails way of ending controller execution after the redirect_to?

Ways I can think of are either to throw an exception after the redirect_to or to return a value from check_date and check it in each action that calls it - something like

def month_index 
  year = params[:year].to_i
  month = params[:month].to_i
  if !check_date(year, month)
    return
  ...
end

But I wonder if there is some nice rails way of doing this. I was half hoping that having called redirect_to rails would recognise I wanted to stop, but that doesn't seem to happen.

A: 

redirect_to just tells rails what to render when it finishes. Rails will get confused if you add other render or redirect_to directives after the one you really want, so just return from the controller after the redirect_to - it's the 'normal' rails way to do things.

+1  A: 

You probably want to use filters.

If you call your check_date as a before_filter in the controller, the fact that it rendered or redirected will prevent the controller from ever calling the action method. It ends there and then.

kch
+1  A: 

You can throw in

return false

wherever you want the code execution in your action to stop

vrish88
actually, just a return will do.
kch
yes but when it is in a private function I have to check return values so I was looking for a more automatic way - like the before_filter
Hamish Downer
+1  A: 

You can also do:

return redirect_to :action => 'index'

and

return redirect_to :action => 'month_index', 
  :year => Date.today.year, 
  :month => Date.today.month,
  :type => params[:type]

since it looks nicer than putting return on it's own line (IMHO)

Slippy Douglas