I having difficulties with the #seller_profile.save statement. Why is it not saving?
def create
#seller_profile = SellerProfile.new(seller_profile_params)
#seller_profile.seller = current_seller
if #seller_profile.save
redirect_to home_index_path
else
puts "Error"
end
end
def current_seller
#current_seller ||= Seller.find(session[:seller_id]) if session[:seller_id]
end
You need to Hanlde your else part with Proper error condition handling
Simple Put will not do the Job
There are following options to handle it
1st by ony Render the JSON
if #seller_profile.save
redirect_to home_index_path
else
render json: #seller_profile.errors.to_json.to_json
end
2nd redirect back with error in notification
if #seller_profile.save
redirect_to home_index_path
else
flash[:error] = #restaurant.errors
redirect_to :back
end
3rd Option to use both Option of Render and Redirect at Same Time
if #seller_profile.save
redirect_to home_index_path
else
respond_to do |format|
format.html { redirect_to :back , flash[:error] = #restaurant.errors }
format.json { render json: #seller_profile.errors.to_json.to_json }
end
end
Related
I have a Rails page that lets the user select one or more records.
This is the controller action:
def addinvtimes
#invoice = params[:invtimes][:invoice_id]
if params[:event_ids] != nil
params[:event_ids].each do |i|
newinvtime = Invtime.new(
linetype_id: 1,
invoice_id: #invoice,
event_id: i.to_i
)
if newinvtime.save
respond_to do |format|
if newinvtime.save
format.html { redirect_to invoice_path(#invoice), :notice => 'Invoice Item was successfully added.' }
else
format.html { redirect_to invoice_path(#invoice), :notice => 'ERROR.' }
end
end
end
end
end
end
There error I get is:
Render and/or redirect were called multiple times in this action
How can I code to not call the redirect multiple times?
Your actual problem is not in the double/redirect error, but in the logic. Assume the params[:event_ids] contain 1000 items. Is where it should to be redirected?
params[:event_ids].each do |i|
if something.save
redirect_to .....
else
redirect_to .....
end
end
You can redirect only once at an action call, but you trying to call redirect in each step of the iterator, I am pretty sure you can't do this.
I have a form that should be submitted after Sign In but all the viewers can see and fill the form. So, I save the parameters in a session variable. After Sign In, I store the parameters successfully. The problem is that I want to add the user_id (which is foreign key) and store it beside the other parameters (before Sign In, the user_id is unknown).
Part of my Controller's code:
def create
if current_user.nil?
session[:trip] = params
redirect_to new_user_registration_path
else
#trip = Trip.new(trip_params)
respond_to do |format|
if #trip.save
...
private
def set_trip
#trip = Trip.find(params[:id])
end
def trip_params
params.require(:trip).permit(:from, :to, :departure_date, :arrival_date, :user_id)
end
As I mentioned, this code stores the new form parameters successfully. To add (insert or merge) the current_user.id, I tried these different ways separetely:
#trip = Trip.new(trip_params.merge(user_id: => current_user.id)
#trip = Trip.new(trip_params)
#trip.user_id = current_user.id
#trip = current_user.Trip.new(trip_params)
#trip = current_user.trips.new(trip_params)
I've tested all of these ways but still the user_id have not been saved!! Please, help me to understand the problem and its solution for Rails4.
It should work.
def create
if user_signed_in?
#trip = current_user.trips.new(trip_params)
respond_to do |format|
if #trip.save
format.html { redirect_to #trip, notice: 'Trip was successfully created.' }
format.json { render :show, status: :created, location: #trip }
else
format.html { render :new }
format.json { render json: #trip.errors, status: :unprocessable_entity }
end
end
else
session[:trip] = params
redirect_to new_user_session_path
end
end
To solve the problem, I've added this new method to the application_controller.rb:
def after_sign_in_path_for(resource)
# save list if there is a temp_list in the session
if session[:trip].present?
#trip = current_user.trips.new(session[:trip]["trip"])
#trip.save
session[:trip] = nil
return #trip
else
#if there is not temp list in the session proceed as normal
super
end
end
I wish it could be useful for the others.
I'm debugging my parks_controller.rb create method because I want to create the park for current user but the current_user method returns nil.
here is the create method:
def create
#park = current_user.parks.new(park_params)
respond_to do |format|
if #park.save
format.html { redirect_to #park, notice: 'Park was successfully created.' }
format.json { render :show, status: :created, location: #park }
else
format.html { render :new }
format.json { render json: #park.errors, status: :unprocessable_entity }
end
end
end
here is the current_user method:
def current_user
if session[:user_id]
#current_user ||= User.find(session[:user_id])
puts "There was no problem"
else
puts "There was a problem"
end
end
It prints out "There was a problem." Here is the user_sessions_controller.rb:
def create
user = User.find_by(email: params[:email])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
flash[:success] = I18n.t("thanks_log_in")
redirect_to parks_path
else
flash[:error] = I18n.t("login_problem")
render action: 'new'
end
end
All of my tests are passing except when I try to save the park to the current user, the tests for POST create in parks_controller_spec.rb start to fail and Im done. What am I doing wrong? Where should I look? I already spent at least 10 hours on this and I'm desperate. Please help. Thanks in advance.
In a model I have:
before_destroy :ensure_not_referenced_by_any_shopping_cart_item
and
def ensure_not_referenced_by_any_shopping_cart_item
unless shopping_cart_items.empty?
errors.add(:base, "This item can't be deleted because it is present in a shopping cart")
false
end
end
When the item is present in a cart, it is not destroyed (which is good), and I see the error if I log it in the action..
def destroy
#product = Beverage.find(params[:id])
#product.destroy
logger.debug "--- error: #{#product.errors.inspect}"
respond_to do |format|
format.html { redirect_to beverages_url }
format.json { head :ok }
end
end
..but the instance variable on which the error message was set is abandoned when the redirect_to happens, so the user never sees it.
How should the error message be persisted to the next action so it can be shown in its view?
Thanks!
I would recommend using a flash message to relay the error information.
respond_to do |format|
format.html { redirect_to beverages_url, :alert => "An Error Occurred! #{#products.errors[:base].to_s}"
format.json { head :ok }
end
Something to that effect. That is how I have handled similar issues in my own apps, but it depends on the detail of information you want to display to the user.
You need to put the error in the flash. Something roughly like
def destroy
#product = Beverage.find(params[:id])
if #product.destroy
message = "Product destroyed successfully"
else
message = "Product could not be destroyed"
end
respond_to do |format|
format.html { redirect_to beverages_url, :notice => message }
format.json { head :ok }
end
end
Note that you also need to be printing out messages in your application.html.erb file.
You can do it with two messages, one with the status OK, and another with NO OK (unprocessable_entity for example, here's more).
def destroy
#product = Beverage.find(params[:id])
respond_to do |format|
if #product.destroy
format.html { redirect_to beverages_url, notice: "Product destroyed successfully", status: :ok}
format.json { head :ok, status: :ok}
else
format.html { redirect_to beverages_url, alert: "Product could not be destroyed", status: :unprocessable_entity}
format.json {head :no_content, status: :unprocessable_entity }
end
end
end
In Rails 4, you can do like that
def destroy
#product = Beverage.find(params[:id])
respond_to do |format|
if #product.destroy
format.html { redirect_to products_url, notice: 'Product was successfully destroyed.' }
format.json { head :ok }
else
format.html { render :show }
format.json { render json: #product.errors, status: :unprocessable_entity }
end
end
end
I want to redirect_to slider_path after a user submits their email. Currently, only the success message is displayed without a redirect. Here's the code:
class Splash::SubscribersController < ApplicationController
def create
#subscriber = Subscriber.new(params[:subscriber])
if #subscriber.save
success = true
message = "Success! We'll let you know when we launch."
else
success = false
message = "Fail."
end
respond_to do |format|
format.html {
if success
flash[:success] = message
redirect_to slider_path
else
flash[:error] = message
end
redirect_to root_path
}
format.json { render :json => { :success => success, :message => message }.to_json }
end
end
end
Just replace this part of your code:
if success
flash[:success] = message
redirect_to slider_path
else
flash[:error] = message
end
redirect_to root_path
with this:
if success
flash[:success] = message
redirect_to slider_path
else
flash[:error] = message
redirect_to root_path
end
Rails API states:
An action may contain only a single render or a single redirect. Attempting to try to do either again will result in a DoubleRenderError:
def do_something
redirect_to :action => "elsewhere"
render :action => "overthere" # raises DoubleRenderError
end
If you need to redirect on the condition of something, then be sure to add “and return” to halt execution.
def do_something
redirect_to(:action => "elsewhere") and return if monkeys.nil?
render :action => "overthere" # won't be called if monkeys is nil
end
Note the use of and return
Neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return".
Add a return statement after your redirect. If the action also renders a template by default, any redirects need to be followed by a return statement.
if success
flash[:success] = message
redirect_to slider_path
return # <= Add a return.
else
flash[:error] = message
end
redirect_to root_path