Double render error rails
Give this a try:
class UsersController < ApplicationController
before_filter :signed_in_user
def create
return back_button if params[:back_button]
@profile = current_user.build_profile(params[:user])
if @profile.nil? || current_user.nil? || @profile.user.nil?
sign_out
return redirect_to signup_path
end
if @profile.new_record?
render 'new'
else
redirect_to more_questions_path
end
end
private
def signed_in_user
unless signed_in?
store_location
return redirect_to signin_url, notice: "Please sign in."
end
end
end
The reasoning behind it: x and return
means x and return nil
, thus returns nil
. Actually, you try to short-circuit the controller action, and return redirect_to ...
.
Render multilpe times - Double render in rails
Call performed?
to check if render
or redirect
has already happened.
You might want to change your to code to something like this:
def check_count
assign_values_from_params
return if performed?
if count >= failed_count
render(partial: params[:view_name], layout: false)
else
render(text: 'works')
end
end
def assign_values_from_params
# code
if @date.blank?
redirect_to(main_index_path) and return
end
# code
end
the AbstractController::DoubleRenderError cannot be fixed with redirect_to and return
The problem is in the show
action, log_in_first
redirects then the show action does whatever it wants, which is redirect or render. This is causing the error.
A better solution is to use before_action
for your authentication and authorization and just let the user controller actions do their thing. Something like the below.
class ApplicationController < ActionController::Base
def current_user
User.find_by :id=>session[:user_id]
end
def log_in?
!!session[:user_id]
end
def authenticate_user!
if !log_in?
session[:error]="You have to log in first to continue your operation"
redirect_to("/login")
end
end
def authorize_user!
unless current_user&.id.to_s==params[:id]
session[:error]="You have no right to do this operation."
redirect_to "/"
end
end
end
class UsersController < ApplicationController
before_action :authenticate_user!, only: [:show]
before_action :authorize_user!, only: [:show]
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
session[:user_id]=@user.id
redirect_to user_path(@user)
else
render 'new'
end
end
def show
@user = User.find_by id: params[:id]
render 'show'
end
private
def user_params
params.require(:user).permit(:name,:password,:email,:email_confirmation)
end
end
How can I avoid double render in this situation?
You don't really need to have the rescue_from StandardError
as this is the default behaviour of Rails. Rails has a middleware called PublicExceptions
which does (mostly) what you want so you can just let the StandardError propagate.
Instead of { error: "Internal Server Error" }
it will render this
{
status: status,
error: Rack::Utils::HTTP_STATUS_CODES.fetch(status, Rack::Utils::HTTP_STATUS_CODES[500])
}
which in case of an exception will render { status: 500, error: "Internal Server Error" }
. This should be a reasonable compromise.
For development you could think about adapting this middleware. You can set it with config.exceptions_app
.
https://guides.rubyonrails.org/configuring.html#rails-general-configuration
https://api.rubyonrails.org/classes/ActionDispatch/PublicExceptions.html
https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/public_exceptions.rb#L14
Why am I getting AbstractController::DoubleRenderError when calling redirect_to in after_action?
By default, Rails will render views that correspond to the controller action. See Rails Guides.
So in your create
and destroy
actions, Rails is performing a render by default. Then your after_action
(which happens after the action) is redirecting, so it's double rendering.
Instead of an after_action
, you could call the goto_articles_page
method in your controller actions.
For example:
def destroy
@comment.destroy
goto_articles_page
end
def goto_articles_page
redirect_to article_path(@article) #return not needed
end
DoubleRenderError but only one render
render
and head
are both methods that perform a render; you only want to call one of them.
# This is all you need
head :ok
Related Topics
Ruby: Differencebetween the Comparatives: "||" and "Or"
Multiple Submit Buttons/Forms in Rails
How to Update Rails Locale Yaml File Without Loosing Comments and Variables
Strong Parameters Not Accepting Array
Split a String into Chunks of Specified Size Without Breaking Words
Exec': String Contains Null Byte (Argumenterror)
What's the "Ruby Way" to Parse a String for a Single Key/Value
Could Not Find Rake with Bundle Exec
Change Value of Request.Remote_Ip in Ruby on Rails
Activerecords Select(:Id).Collect VS. Pluck(:Id) Methods: Why Is Pure Ar "Pluck" Slower
Custom_Require.Rb:36:In 'Require': No Such File to Load -- Myapp(Loaderror)
Need to Use Add_Index on Migration for Belongs_To/Has_Many Relationship? (Rails 3.2, Active Record)
Colorized Output Breaks Linewrapping with Readline
Parse Large JSON Hash with Ruby-Yajl
Ruby - Extracting the Unique Values Per Key from an Array of Hashes