Topic: redirect back generically?

Hey all,

My app allows users to upload images. These images end up in different parts of their profile and show up in many different places throughout my website. Whenever a user uploaded image is displayed, it's wrapped in a "report_abuse" partial that includes a tiny link just below the image where people can click if the image is offensive.

Clicking the 'report abuse' link is just this

<%= link_to 'report this image', :controller => 'image', :action => 'report_abuse', :id => image %>

and the action is something like this

def report_abuse
    abuse = ImageAbuse.new(:image_id => params[:id])
   
    abuse.save
   
    flash[:notice] = 'the image has been reported for abuse'

    # this is obviously not a real method smile   
    redirect_to_wherever_the_heck_they_where_when_they_clicked
end


How can I implement 'redirect_to_wherever_the_heck_they_where_when_they_clicked'? Is it possible to do so generically? Can rails say look at the "request stack" or something like that? I REALLY don't want to have to include a parameter in the call to tell report_abuse where to return to.

I could do this particular example with AJAX (and may just do that), but in general, I'd like to know how to do this or know that it's generally not possible.



oh, and acts_as_authenticated has "redirect_back_or_default", but it doesn't seem to work.

Last edited by tortoise (2006-12-29 10:37:48)

Re: redirect back generically?

Hmm, the first thing that comes to mind would be to add a before filter to application controller that stores the current URL in the flash.  Thus you can always get the previous page from the flash when needed.

There's probably many better ways, but....

My RoR journey  -- thoughts on learning RoR and lessons learned in applying TDD and agile practices.

Re: redirect back generically?

Try this. Not sure if it will work for all cases though.

def report_abuse
  ImageAbuse.create(:image_id => params[:id])
  flash[:notice] = 'the image has been reported for abuse'
  redirect_to :back
end

Have you considered doing this through AJAX? Seems like it would be a better UI so the page doesn't have to reload. It will also stop some bots from abusing the abuse button. wink

Railscasts - Free Ruby on Rails Screencasts

Re: redirect back generically?

Yeah i mentioned for this particular example AJAX may be better. But I'm more curious on how to do this in general. I'm at work right now so I'm drawing a lot of blanks, but I remember coming across this need a lot during development.

I will try redirect_to :back, didn't know about that. I also like the filter idea if need be. Seems like a heavy, but generic and easily maintained solution to the problem.

Re: redirect back generically?

I've done something similar. The user can report a problem on any page but I give them an email form. From the email form, they can describe the problem and optionally tell me the URL they thought they got the error on. Behind the scenes, I include in the email the exact URL they were on when they clicked the link to report the problem. This is session[:original_uri] in the code below. As you can see, I also maintain a back_uri so that each page can always have a back link. I had to filter out URLs including the text problem_report or else I never would have gotten the correct URL in the problem report.

I'm not sure how well this will work in practice and I'm open to suggestions and constructive criticisms. I'm sure I'll need to add filtering on the back_uri, or else it might cause problems after certain user actions. I probably need to also make the abuse link work through a post, or use some other method to avoid the bots problem ryanb mentioned.

I should also rename the method set_original_uri since it also set the back_uri now.

This code is in my application controller:

  before_filter :set_original_uri

  def set_original_uri
    @back_uri = session[:original_uri]
    if (request.request_uri =~ /problem_report/).nil?
      session[:original_uri] = request.request_uri
    end
  end

Re: redirect back generically?

Another option, that might be worth looking at if this is a common need (probably not in the report abuse case, you're describing) would be to flip it around -- have the link basicly point right back to the current request, but tack on a "report_abuse=true" to the request parameters.  Then have the application wide before filter that checks for the presence of that parameter before processing the report with control flowing normally to the  normal action.

This could save the redirect.  Similar to the AJAX approach, but without required JS, etc.  Not worth the complexity though unless the percentage of actions expected to flow though the system is high, so not useful in your case, but in regards to the thread in general......

My RoR journey  -- thoughts on learning RoR and lessons learned in applying TDD and agile practices.

Re: redirect back generically?

Or, also simple:

<%= link_to 'report this image', :controller => 'image', :action => 'report_abuse', :id => image, :return_to => @request.uri %>

def report_abuse
  ImageAbuse.create(:image_id => params[:id])
  flash[:notice] = 'the image has been reported for abuse'
  redirect_to params[:return_to] || :back
end