views:

371

answers:

4

Hello,

I want to store the current URL in a session variable to reference the previous visited page.

If I store every URL (via a before_filter on ApplicationController), also actions which end in a redirect (create, update, etc) are considered as last visited page.

Is there a way to tell Rails only to execute a function if a template is rendered??

Update

Thanks for the after_filter tip... having written so many before_filters I didn't see the obvious. But the Trick with @performed_redirect doesn't work-

This is what I got so far

class ApplicationController < ActionController::Base

  after_filter :set_page_as_previous_page

  def set_page_as_previous_page
    unless @performed_redirect
      flash[:previous_page] = request.request_uri
    else
      flash[:previous_page] = flash[:previous_page]
    end
  end

end

I need to implement a "Go Back" Link, without the use of Javascript, the HTTP Referer. Sorry If I should have mentioned that, I appreciate your help!

Update 2

I found a solution, which is not very elegant and only works if your app follows the standard naming scheme

def after_filter   
    if File.exists?(File.join(Rails.root,"app","views", controller_path, action_name+".html.erb"))
      flash[:previous_page] = request.request_uri
    else
      flash[:previous_page] = flash[:previous_page]
    end
  end
A: 

Can be a bit more specific? I cant get your question- by template you means render :view, the layout? or only when called with render :template?

Rendering a page? render :action=>:new is a page too... Can you be a bit more specific on which you want to capture and which you want to exclude?

Saw the accepted answer :)

goodwill
I mean rendering a page, as opposed to a redirect to another action.
Josti
A: 

The controller will have these variables, which might be helpful:

@performed_render
@performed_redirect

But anyway, how exactly are you storing the url? Show us the filter code. Why not using an after_filter?

kch
I tried your advice without succes, though I think it is the right direction
Josti
+2  A: 

Not sure why @performed_redirect isn't working, you can see that it does exist and have the desired values by calling the actions on this test controller:

class RedirController < ApplicationController
  after_filter :redir_raise

  def raise_true
    redirect_to :action => :whatever
  end

  def raise_false
    render :text => 'foo'
  end

  private

  def redir_raise
    raise @performed_redirect.to_s
  end

end

As an aside, instead of doing

flash[:previous_page] = flash[:previous_page]

you can do

flash.keep :previous_page

(My patch, that. back in the days :P)

kch
Nice!I think @performed_render does work... my bad! I didn't think of my thumbnail action sending an image via send_file, not redirect, thus counting as render, though not being a rendered page. It is only invoked by an image_tag.
Josti
A: 

Another possible approach to determine whether the response is a redirect vs. render is to check the status code:

class ApplicationController < ActionController::Base

  after_filter :set_page_as_previous_page

  def set_page_as_previous_page
    unless 302 == request.status  #redirecting
      flash[:previous_page] = request.request_uri
    else
      flash[:previous_page] = flash[:previous_page]
    end
  end

end

It really seems like there should be a redirect? method in ActionController::Base for this.

Travis