Forward the user back to a post after adding a comment - ruby-on-rails

This is probably a fairly simple thing to do - I have a site with a news feed that shows various posts. There are also other pages that similarly show posts. Comments can be added to these posts directly from any of these pages.
What I need to do is redirect the user back to the URL they came from, once they've added a comment, and to the particular post they commented on (each post has an id of post-#{post.id}, so I'd just have to stick #post-2 or whatever to the URL.
If the post could not be saved, for whatever reason, I'd also like to have the content that the user had submitted pre-filled into the comment box after the redirect.
How can I do these two things? The first is the more important one..
I'd have to store the URL that the user is coming from in the session on the new action and redirect to this on the create action? How can I get the URL?
I'm on Rails 3.1 by the way.
Thanks for the help!

You could use redirect :back which will send the user back to the page that issued the request
redirect_to :back

Assuming Comment is a resource nested under Post in your routing (/posts/123/comment/new):
def create
comment = Comment.new(params[:comment])
if comment.save
redirect_to post_path(comment.post)
else
redirect_to new_post_comment_path(params)
# or maybe you have the comment form on the Post#show page
# redirect_to post_path(params)
end
end

Related

Redirect from custom devise edit page

I am using devise for user registrations. I set up a custom edit page '/info' to use as an additional signup page. The only problem is after you submit the edits on the info page it redirects to the user profile. I am able to change it redirect to the home page (where I want after /info) but then it also redirects there from the normal edit page. I am not sure how to redirect based on what page the user is on.
My one idea was to get the users current path and use an if statement but I haven't been able to get that to work.
registrations_controller.rb:
def update
...
current_uri = request.env['PATH_INFO']
if current_uri == '/info'
redirect_to root_path, notice: "Welcome"
else
redirect_to user_path(#user)
end
end
Normally it just looks like this:
def update
...
redirect_to user_path(#user)
end
The problem seems to be you need to keep data around to determine where to redirect. A few ideas:
You could store data in the session when a user visits a previous page and check this data in your action to determine where to redirect the user. The session is often a convenient place to store things that are consistent between requests but that should not be persisted to the database.
You could store data in the database (for instance, add a flag to your user model) and check this to determine where to redirect.
You could check request.referer and redirect based on the value there. This may not be as reliable.

Error when deleting a page

I am new to Ruby on Rails and I am creating a basic blog application.
I am getting the following error when I have confirmed that I want to delete a post/page.
ActiveRecord::RecordNotFound in
PagesController#destroy
Couldn't find Page with ID=21
{"authenticity_token"=>"JjjfnpIn4ogYhLWnbyGHjwLsy6YSgDHL+GZfOqkhSow=",
"_method"=>"delete", "id"=>"21"}
I want the user to be redirected to the listing page when they have deleted the post, I understand that it looks as though problem is with the destroy action in the controller.
My code in there is currently:
def destroy #Destroy action
#page = Page.find(params[:id])
#page.destroy
redirect_to page_url
I appreciate any advice on this.
if you're deleting a Page, you shouldn't redirect back to it because.. it won't exist
maybe try redirect_to pages_url instead of page_url

Rails Way to Restrict Page Access Without Sessions

Context
I'm building a super simple, knock-your-socks-off sexy sign-up page at http://hivechatter.com. (Yes, I feel strongly about her.)
The root page is the new user action, where I ask for email only. If the visitor submits a valid email, a new user is created and I redirect to that user's edit page and ask for additional, optional info.
Problem
The edit page url is of the usual form: http://hivechatter.com/users/19/edit. One can visit any user's edit page by simply visiting this url with whichever id number they choose.
Question
How do I restrict access to the edit user page so that it can only be visited once, and only immediately after having created that user_id from the root new user page?
I can think of a variety of methods to explore. I'd appreciate a pointer on the most elegant, rails way to do this. Note that I don't need any additional functionality like sessions, etc. This two step sign-up process is the extent of what I need right now.
Thanks!
Add new column to your users table. Let it be opened_once:boolean with DEFAULT false
Then in your users_controller
def edit
#user = User.find( params[:id], :conditions => ['opened_once => ?', false] ) rescue ActiveRecord::RecordNotFound
#user.update_attribute :opened_once, true
...
end
so now it can be showed only once right after creating new user when you redirect to edit page
UPD
What you can do more Rails way? Without adding new stuff to your database and so on. You can remove your edit action at all, so your edit view will rendered at create:
def create
#user = User.new params[:user]
respond_to do |format|
if #user.save
format.html{ render :action => :edit }
else
format.html{ render :action => :new }
end
end
end
User will see edit form only once if validation passed and his profile created.
So this is specific "Rails way" :)
The point of a cookie is to maintain state in the form of a session. HTTP by spec is stateless, and there for if you have people logging in then they need a session. RoR has a great session handler, I recommend using it.
The only other way to restrict access would be using a .htaccess file or similar method of doing basic-auth. This doesn't scale well and is less secure.

Rails: create from two pages

I'm very new to Rails, so maybe I'm just missing the "Rails way" of doing this, but I have a model, call it Post. I can create a post from the canonical posts/new page but also from another page, say home/index.
In home/index i have a form_for #post (slightly different from the one in posts/new, but say that i can use a partial). The problem is that in the PostController.create I cannot pass the newly created #post object back to home/index (in case of errors) because:
if I don't specify a page to render, it will automatically render posts/new
i don't know the calling page in order to redirect it to the right calling page (posts/new or home/index)
even if i knew it (hacking the request referrer or using redirect_to :back), redirect_to doesn't pass objects back, so that #post is empty when called from home/index
Any help? thanks
EDIT
Maybe a possible solution would be to get the calling controller / action from the request and render it back. Any way to do this?
In theory, you could achieve what you're trying to do by checking the referer:
def create
#post = Post.new
if #post.update_attributes(params[:post])
# redirect as appropriate
else
render :action => case request.referer
when new_post_path then "posts/new"
when "/" then "home/index" # assuming that home/index is the root of the site
end
end
end
To get the referrer page, you can make a hidden field with the name redirect. You can use it in the controller.
redirect_to params[:redirect] || posts_path
Have you tried that you pass the post's id in the query string to the home/index
eg: /home/index?post_id=42
You can find out who called your page by looking at
request.referrer
I don't know if this is the "rails way" but here's my solution.
You can add a route for
match home/index/(:id) => "home#index"
and redirect to this after creating the Post. Then in your Home controllers index action just do a
#Post = Post.find(params[:index]) if params[:index]
Your view should display the post if #Post exists
I like this approach because it keeps all the logic where it should be. Routing logic in the controller and view logic in the views.

Rails 2.3 - Redirection Issues

I have an application where folks search for an item. If the item is found, they are presented with a list of related items found by parameters in the URL AND a contact form. I'm having issues redirecting the visitor back to the same page (with the URL parameters) after submitting the form.
Any ideas?
Try redirect_to(:back).
You could use redirect_to :back, but note that this depends on the Referer header being set, and you'll run into an error if it's not for some reason.
To get around this, I use a method like the following in my application (I put it into ApplicationController so it's accessible in all my controllers):
def redirect_back_or_to(options = {})
if request.env["HTTP_REFERER"].blank?
redirect_to options
else
redirect_to :back
end
end
Which will redirect back if the Referer header is set and otherwise work like a normal redirect_to (so you can specify where to redirect to by default).

Resources