Not working flash messages with respond_to in Rails 3.2 - ruby-on-rails

I have this simple action (originally generated by scaffold):
def destroy
#item = Item.find(params[:id])
#item.destroy
respond_to do |format|
format.html { redirect_to :back, :success => 'Post was successfully removed.' }
format.json { head :no_content }
end
end
The page is redirected back, but the alert message is not shown. (snippet for displaying flash messages works well in the whole application, but not here)
What's the problem here?
Thanks

Try this:
format.html { redirect_to :back, :flash => {:success => 'Post was successfully removed.' }}

The flash key is either :notice or :alert. There is no :success key.

Related

Rails redirect to the post after a comment is made

I have a comment form on my tickets show page. I can fill it out, but when submitting the comment, it goes to the comments show page. I need this to just go back to the ticket it was showing.
I have this code at the moment:
comment_controller.rb
def create
#comment = Comment.new(comment_params)
respond_to do |format|
if #comment.save
format.html { redirect_to #comment, notice: 'Comment was successfully created.' }
format.json { render :show, status: :created, location: #comment }
else
format.html { render :new }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
and a similar thing with the destroy method
def destroy
#comment.destroy
respond_to do |format|
format.html { redirect_to comments_path, notice: 'Comment was successfully destroyed.' }
format.json { head :no_content }
end
end
I'm not sure how to get it to remember which ticket it was on, for it to redirect to.
I have entered the associations with the models with ticket.rb and comments.rb
You can just replace the
redirect_to comments_path
with
redirect_to :back
# or
redirect_to(:back)
which after the comment is made, it returns to the previous page
If you're using rails 5, use
redirect_back(fallback_location: root_path)
instead

Can I use a helper method in a redirect method call?

I am using Rails 5 and I am trying to use this redirect_back method.
However, my issue is that I am using it for a Comment#Create which can be called for both a Question & Answer object. So depending on which it is, I want it to redirect back to that respective object (which have two different routing paths ofcourse).
So, what I have done is created a concern, added a custom method and then attempted to call that method in the redirect_back call but it doesn't seem to be working.
The concern looks like this:
module CommentRedirect
extend ActiveSupport::Concern
def question_or_answer(comment)
if comment.commentable_type.eql? "Question"
question_path(comment.commentable)
elsif comment.commentable_type.eql "Answer"
question_path(comment.commentable.question)
end
end
end
Then my Comment#Create looks like this:
format.html { redirect_back(fallback_location: question_or_answer(#comment)), notice: 'Comment was successfully created.' }
The error I get is this:
SyntaxError at /comments
syntax error, unexpected ',', expecting '}'
... question_or_answer(#comment)), notice: 'Comment was success...
...
Given that this is the redirect_back code in Rails:
def redirect_back(fallback_location:, **args)
if referer = request.headers["Referer"]
redirect_to referer, **args
else
redirect_to fallback_location, **args
end
end
Can I use the helper method in the way I am attempting?
If not, how else can I achieve what I want to do?
Edit 1
This is the entire Comment#Create method:
def create
#comment = Comment.new(comment_params)
#comment.user = current_user
respond_to do |format|
if #comment.save
format.html { redirect_back(fallback_location: question_or_answer(#comment)), notice: 'Comment was successfully created.' }
format.json { render :show, status: :created, location: #comment }
else
format.html { render :new }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
I didn't notice right away either, but your line is not valid syntax:
format.html { redirect_back(fallback_location: question_or_answer(#comment)), notice: 'Comment was successfully created.' }
It should be this:
format.html { redirect_back(fallback_location: question_or_answer(#comment), notice: 'Comment was successfully created.') }

How to put multiple lines of code into a format.html block?

My controller is
def destroy
#image.destroy
respond_to do |format|
format.html
format.json { render json: 'success' }
end
end
I want that request from html then it redirect to :back like
flash[:notice] = "Image Successfully deleted"
redirect_to :back
it works fine when I can't deal with json. I want to combine both of them so they send response accordingly to html or ajax request
You can just put it inside the respond_to block for the html format
def destroy
#image.destroy
respond_to do |format|
format.html do
flash[:notice] = "Image Successfully deleted"
redirect_to :back
end
format.json do
render json: 'success'
end
end
end
You can put multiple lines into a block.
respond_to do |format|
format.html do
flash[:notice] = "Image Successfully deleted"
redirect_to :back
end
format.json { render json: 'success' }
end

Rails session store stopped working correctly

I have a Rails 3.2 app that uses session store in the controllers to get the user back to the screen they were previously on.
It's been working fine for over a year. All of a sudden, the production version on Heroku, has started having issues. The user is looking at a worequest and clicks on the following in order to add a comment.
<%= link_to 'New Comment', new_comment_path(:worequest_id => #worequest.id), :class => 'btn btn-primary' %>
This is the code I use:
def new
#comment = Comment.new
#comment.build_attachment
#worequest = params[:worequest_id]
session[:return_to] ||= request.referer
respond_to do |format|
format.html # new.html.erb
format.json { render json: #comment }
end
end
# POST /comments
# POST /comments.json
def create
#comment = Comment.new(params[:comment])
respond_to do |format|
if #comment.save
if session[:return_to] != nil
format.html { redirect_to session.delete(:return_to), notice: 'Comment was successfully created.' }
format.json { render json: #comment, comment: :created, location: #comment }
else
format.html { redirect_to :back, notice: 'Comment was successfully created.' }
format.json { render json: #comment, comment: :created, location: #comment }
end
else
format.html { render action: "new" }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
In development and staging (on Heroku), the user goes back to the worequest after entering a new comment.
Now in Production, the url looks like this:
mywebsite/comments instead of mywebsite/worequests/639
I'm not even sure where the session[:return_to] gets stored. Therefore, I'm having trouble debugging the issue.
Thanks for your help!!
Are you able to replicate this behavior 100% of the time, or just seeing it sometimes in your log?
It looks like someone is getting to comments#new from /comments (comments#index). Is there a route to /comments?
Run rake routes to see all your routes.
If there is a route to comments#index, and there's no reason for it to be exposed because you only intend for people to post comments from within the context of a specific article, consider removing it the comments#index route.
Also, one thing to consider, request.referrer is not always available. It's sent by the client who may choose not to send it (e.g. certain privacy extensions remove this header).

Ruby on Rails - updating multiple models from the one controller

I'm trying to get my head around saving to multiple models from the one controller and it's probably really simple but I can't figure it out.
I have a User Model that has many loanitems and the loanitems belong to the user associations set up.
In my loanitems controller I want each loanitem create action to update a the user.points
So at the moment I have the following code that doesn't throw any errors but doesn't update the user model either.
def create
#loanitem = current_user.loanitems.build(params[:loanitem])
respond_to do |format|
if #loanitem.save
#loanitem.user.points = #loanitem.user.points + 50
#loanitem.user.save
format.html {redirect_to root_path, :flash => {:success => "Loan Item created" } }
format.xml{render xml: root_path}
else
format.html {render 'pages/home' }
format.xml {render xml: 'pages/home'}
end
end
end
I'm also trying the following variation on a theme
def create
#loanitem = current_user.loanitems.build(params[:loanitem])
respond_to do |format|
if #loanitem.save
current_user.points = current_user.points + 50
current_user.save
format.html {redirect_to root_path, :flash => {:success => "Loan Item created" } }
format.xml{render xml: root_path}
else
format.html {render 'pages/home' }
format.xml {render xml: 'pages/home'}
end
end
end
But should I be sending some message instead to the userupdate controller instead? That currently looks like this ...
def update
#user = User.find(params[:id])
if
#user.update_attributes(params[:user])
redirect_to #user, :flash => { :success => "Profile has been updated!"}
else
#title = "Edit Profile"
render 'edit'
end
end
Or I have heard that the business logic really should all be contained in the model so maybe the method should be written in User.rb and then called by the Loanitems controllers create method?
I know it's a real rookie question but any advice would be really welcome.
It sounds like you need to use a Transaction, so you can modify multiple items as a single atomic unit:
def create
respond_to do |format|
User.transaction do
begin
#loanitem = current_user.loanitems.create!(params[:loanitem]) # raises exception if it can't create
#loanitem.user.update_attributes!(:points => #loanitem.user.points + 50) # raises exception if it can't update
format.html {redirect_to root_path, :flash => {:success => "Loan Item created" } }
format.xml{render xml: root_path}
rescue ActiveRecord::RecordInvalid
format.html {render 'pages/home' }
format.xml {render xml: 'pages/home'}
raise ActiveRecord::Rollback
end
end
end
end
This allows you to have a simple happy-path where multiple objects are updated/created and roll-back all changes so far if anything goes wrong and render your error handling logic. The objects will have the validation messages you can display to the user.

Resources