Double Render Error Rails

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



Leave a reply



Submit