9

I have a blogging application that has posts that can receive votes through a vote action in the posts controller. Because I allow voting in both the index and show views, I redirect_to :back after a vote is made, as below.

def vote
  # voting logic goes here
  redirect_to :back
end

This redirects me to the correct page, but I want to redirect to the specific post within the page. To do this, I added an identifying anchor to my post partial div.

<div id="post_<%= post.id %>">
  <%= post.content %>
</div>

How can I reference this in my redirect_to :back? I tried the below, which doesn't work.

# this doesn't work!
redirect_to :back, anchor: "post_#{@post.id}"

Alternatively, if I were to use an if clause for the show and index views, how do I do that? I tried the below, which returns undefined method 'current_page' for VocabsController.

#this doesn't work!
if current_page?(posts_path)
  redirect_to posts_path(anchor: "post_#{@post.id}"
else
  redirect_to @post
end
umezo
  • 1,519
  • 1
  • 19
  • 33

4 Answers4

12

Deep in Rails redirecting mechanism, :back simply means redirect to whatever in HTTP_REFERER environment variable (or raise an error if nothing in this variable). So before redirect_to :back in your controller add this line: env["HTTP_REFERER"] += '#some-id', this should do it.

Ahmad Sherif
  • 5,923
  • 3
  • 21
  • 27
1

EDIT: ok my bad, got confused. you should look into this:

What's the right way to define an anchor tag in rails?

EDIT2:

the problem you have is that you are calling a helper inside a controller and not inside a view.

I encourage you to look into the view_context method

http://jhonynyc.tumblr.com/post/5361328463/use-view-context-inside-rails-3-controller

Community
  • 1
  • 1
Kevin Smouts
  • 146
  • 2
  • 8
  • Hi @Kevin. Thanks for the input. It seems my first option (using `:back`) won't work, as it won't accept the anchor. The second option (using if clause) seems ok, and the view_context method works. How would I say, "if you voted for a post on the index page"? Using `current_Page?(posts_path)` doesn't work, probably because it's called within a different action (ie. not the index action). How can I say, "if I vote for a post on the index page, redirect to that post on the index page, else redirect to that post's show page" – umezo Dec 10 '12 at 04:03
  • 2
    I think what you want to do is not to use an action redirecting the user but actually have the user voting for the post without being redirected anywhere (staying on the same page where he voted). So my advice is to use a simple ajax link: it executes the given method without changing the current view of the user. EDIT: here is the code you would need `<%= link_to_function "Vote up", "$.ajax({type: 'GET', url: '/your_controller/voteup/'})" %>` – Kevin Smouts Dec 10 '12 at 09:22
  • Good point. that's more or less what I did. Thanks for the input. – umezo Dec 10 '12 at 19:47
0

I ended up using Javascript instead.

posts_controller.rb

def vote
  @post = Post.find(params[:id])
  #voting logic
  respond_to do |format|
    format.html { redirect_to :back }
    format.js
  end
end

posts/_post.html.erb

<div class="post_partial" id="post_<%= post.id %>">
  <%= post.content %>
  <div id="vote_button_<%= post.id %>">
    <%= link_to "up", vote_path, method: "post", remote: true %>
  </div>
</div>

posts/vote.js.erb

$('#post_<%= @post.id %>').html('<%= j render @post %>');
umezo
  • 1,519
  • 1
  • 19
  • 33
0

Under the hood, redirect_back(fallback_location: 'some_path') redirects_to request.referrer and falls back to 'some_path' when things go wrong.

Unfortunately, it does not provide for supplying an anchor. You can work around this by writing a simple private method to simulate it.

def back_with_anchor(anchor: '')
  "#{request.referrer}##{anchor}"
end

You can then do this where needed.

redirect_to back_with_anchor anchor: @record.id
echelon
  • 101
  • 1
  • 5