Which one is right to use? flash[:notice] = 'some msg' or :notice = 'some msg'?
I have met both options, but there is no explanations about difference. So I confused which one is right to use. Maybe it's the same?
If you have a controller with an action, such as the following:
def create
#activity = Activity.new activity_params
if #activity.save
flash[:notice] = 'Activity was successfully created!'
redirect_to activity_path(#activity)
else
render :new
end
end
Then you can use flash[:notice] and set the flash hash's notice to Activity was successfully created!.
However, you are correct, when using redirect_to you can pass :notice as an option, as such:
def destroy
if #activity.destroy
redirect_to activities_path, notice: 'Activity was successfully destroy!'
else
flash.now[:notice] = 'Activity was not destroyed.'
end
end
If you check the ActionController::Redirecting module you will see that notice can be passed as an option.
Fundamentally, these two things do the same thing. They are just being set differently.
Hope this helps!
Related
I'm actually working on a small app, where a user can create an event. It has to be done in three steps.
To achieve this, I created two custom actions in the related controller. Each view has a form using the update url.
Then I customized the update method this way:
def training
#event = Event.find(params[:event_id])
#coach = Coach.find(#event.coach_id)
end
def confirm
#event = Event.find(params[:event_id])
end
def update
respond_to do |format|
if #event.update(event_params)
if params[:commit] == 'next'
format.html { redirect_to booking_event_confirm_path(#event), notice: 'Event was successfully updated.' }
else
format.html { redirect_to booking_event_path(#event), notice: 'Event was successfully updated.' }
end
else
if params[:commit] == 'next
format.html { render :training }
else
format.html { render :edit }
end
end
end
end
As a Rails beginner, I would be happy to get some feedback... Does this seems ok, or would it be a better way to achieve my goal?
Thx in advance!
Your solution is not bad, but there is a better way to achieve it. I would suggest you checking Wicked gem and this tutorial.
In general, google a wizard or multi-step form.
I have a create action in my controller.
def create
#client=Client.find(params[:client_id])
#comment= #client.build_comment( comment_params )
if #comment.save
flash[:success]= "Thank you!"
redirect_to path_one
else
render action: :new
end
end
private
def comment_params
params.require(:comment).permit(:response, :experience)
end
Now in my create action, whenever my client submits the form, I want to be able to redirect to different paths based on the value of "experience".
So, if the experience is "positive", I want them to go to path_one and if the experience is "negative", I want them to go to path_two.
I tried this:
def create
#client=Client.find(params[:client_id])
#comment= #client.build_comment( comment_params )
if #comment.save
if params[:experience]=="positive"
flash[:success]= "Thank you!"
redirect_to path_one
else
render action: :new
else
redirect_to path_two
end
end
end
private
def comment_params
params.require(:comment).permit(:response, :experience)
end
But this always redirects to the same path.
Try this:
if #comment.save
if comment_params[:experience]=="positive"
flash[:success]= "Thank you!"
redirect_to path_one
else
redirect_to path_two
end
else
render action: :new
end
the field experience is not inside params, but inside params[:comment] (or, in this case, inside the comment_params method)
The else parts of your if statement are in the wrong order. Try this:
if #comment.save
if params[:experience]=="positive"
flash[:success]= "Thank you!"
redirect_to path_one
else
redirect_to path_two
end
else
render action: :new
end
I would like to render on the same page if email is blank. However, when I leave in blank instead of staying on users/new. It goes to /users. It is still render to _from for the URL is different.
def new
respond_with(user)
end
def create
if user.save
user.send_invitation
redirect_to root_url, notice: "Signed up!"
else
render "/users/new"
end
end
def destroy
#user = User.find(params[:id])
if #user.destroy
redirect_to root_url, notice: "User was deleted successfully!"
end
end
def edit
respond_with(user)
end
def update
params[:user].delete(:password) if params[:user][:password].blank?
params[:user].delete(:password_confirmation) if params[:user][:password_confirmation].blank?
if user.save
redirect_to users_path, :notice => "Saved your updates!"
else
render :edit
end
end
render "/users/new"
Just renders template users/new, at create action. So the URL stays /users.
You can try to
def create
if user.save
user.send_invitation
redirect_to root_url, notice: "Signed up!"
else
redirect_to new_user_path
end
end
But then you will have no access to submitted params, so the form will be clear.
The thing in here I think it's a routes problem, as you want to persist the URL.
What Rails does in this cases is it goes to the create action once the form was submitted and if for some reason the record is not being save(in this case) you are rendering the new action but with the object which has errors and data.
To clean up a little bit you could do something like:
def create
if user.save
user.send_invitation
redirect_to root_url, notice: "Signed up!"
else
render :new
end
end
In my opinion, don't try to bend Rails this way, you'll get a lot of problems with it and also, does it really matters to persist the URL?
Redirection is not an option, because you'll loose all the data from the request, as it would become a new request due to the redirect.
Hope this helped!
def create
#purchase = Purchase.new(params[:purchase])
if session[:purchase_id] != #purchase.save
redirect_to(#purchase, :notice => "Thank you. You good lookin person you.")
end
end
I'm trying to either
A - Redirect to a URL, or other controllers path, or
B - refresh the form they ordered from (the new_purchases_path) and flash :notice the user that their purchase was successful. When I try to add a Url (that would be a thank you message page) i get syntax errors. This code redirects the user to the index list (which is inaccesible to them)
If I take out the def create, it by default flashes a notice and shows them their completed form. I'm using simple_form and I'm not sure how to override those defaults. Any suggestions on at least redirecting to a url?
Examples:
A - Redirect to a URL, or other controllers path
redirect_to :action => "show", :id => 5
redirect_to "http://www.rubyonrails.org"
redirect_to new_purchases_path
redirect_to purchases_url
redirect_to :back
B - refresh the form they ordered from (the new_purchases_path)
render :action => "new"
Edit:
Here a general example with flash messages:
if #foo.save
redirect_to foos_path, :notice => "Foo saved"
else
flash[:notice] = "Some errors occured"
render :action => "new"
end
here is an example of a create method i made today
def create
#book = Book.new(params[:book])
if #book.save
redirect_to searchbook_path, notice: 'Book was successfully saved'
else
render :action => 'results'
end
end
So in your case you could maybe try this
def create
#purchase = Purchase.new(params[:purchase])
if #purchase.save
redirect_to purchase_path, :notice 'Thanks for your purchase'
else
render :action => 'new'
end
end
This is assuming that you have a purchase and new path... Though it would help if you could let us know what errors you are getting
I have been trying to get to grips with jQuery and been following a railscast on adding an Ajax add review form, which works fine but I would now like to add into it the ability for a review to belong to a user as well as a venue.
Reviews controller
def create
#review = Review.create!(params[:review])
#review.venue = #venue
if #review.save
flash[:notice] = 'Thank you for reviewing this venue!'
respond_to do |format|
format.html { redirect_to venue_path(#venue) }
format.js
end
else
render :action => :new
end
end
views\reviews\create.js.erb
$("#new_review").before('<div id="flash_notice"><%= escape_javascript(flash.delete(:notice)) %></div>');
$("#reviews_count").html("<%= pluralize(#review.venue.reviews.count, 'Review') %>");
$("#reviews").append("<%= escape_javascript(render(:partial => #review)) %>");
$("#new_review")[0].reset();
I have tried changing the controller to:
def create
#review = #current_user.reviews.create!(params[:review])
#review.venue = #venue
if #review.save
flash[:notice] = 'Thank you for reviewing this venue!'
respond_to do |format|
format.html { redirect_to venue_path(#venue) }
format.js
end
else
render :action => :new
end
end
but it just wont submit, with no errors.
I think I have the models set correctly with belongs_to and has_many, I think this is a controller issue I'll add other code bits if needed.
Development log
NoMethodError (undefined method `reviews' for nil:NilClass):
app/controllers/reviews_controller.rb:14:in `create'
Thanks for any help!
It appears that your error is residing with #current_user. According to your development log, #current_user is nil when you call #current_user.reviews on it. I would say track down where this #current_user instance variable is being set and find out why it is nil. Now, what kind of authentication are you using? Most authentication plugins, especially those used by Ryan Bates of the Railscasts you mentioned, use a local variable, say just current_user, as the means to access the currently signed in user. I know I do in all my code.
So, rewrite the line as
#review = current_user.reviews.create!(params[:review])
and see if that works. If it doesn't, change it back and then track down where this #current_user is being set. Chances are good it is being set in a before_filter :method_name at the beginning of your controller.
Calling create! (with exclamation mark) will throw an exception and thus abort your create action if saving fails. Check your log/development.log for these exceptions.
Use build instead of create and lose the exclamation mark.
def create
#review = #current_user.reviews.build(params[:review])
#review.venue = #venue
if #review.save
flash[:notice] = 'Thank you for reviewing this venue!'
respond_to do |format|
format.html { redirect_to venue_path(#venue) }
format.js
end
else
render :action => :new
end
end