rails 4: AbstractController::DoubleRenderError 格式
rails 4: AbstractController::DoubleRenderError with format
我正在通过 Ajax 请求创建组记录,并收到此错误(在这两种情况下,@group 有效或无效)
Started POST "/groups" for ::1 at 2015-10-28 17:47:08 +0100
Processing by GroupsController#create as JS
AbstractController::DoubleRenderError - Render and/or redirect were called multiple times in this action. Please.....
我不明白为什么,因为重定向和呈现不在同一个块中...
这是我的控制器
class GroupsController < ApplicationController
respond_to:html,:js
def create
@group = Group.new(company_id: current_user.company_id, name: params[:name] )
if @group.save?
respond_to do |format|
format.html { redirect_to groups_path, notice: 'Group was successfully created.'}
format.js
end
else
respond_to do |format|
format.html { redirect_to new_group_path }
format.js
end
end
end
...
错误似乎是在尝试渲染 create.js
时发生的
Rendered groups/create.js.erb (6.5ms)
Completed 500 Internal Server Error in 48784ms (Views: 46.2ms | ActiveRecord: 4.7ms)
这是一个相当标准的 .js.erb 文件
<% if @group.errors.blank? -%>
$('#groupModal').modal('hide');
<% else %>
$( "#modalGroupAlert" ).removeClass('alert-info');
$( "#modalGroupAlert" ).addClass('alert-danger');
$( "#modalGroupAlert span" ).replaceWith( "<span><%= nicer_display_errors(@group.errors) %></span>" );
$( "#modalGroupAlert" ).show();
<% end %>
这是怎么回事?为什么?感谢反馈
更新 1 =======
根据 Pavan 的评论,我更新了创建代码,并且还添加了响应程序 gem(rails 版本 4.2.4:不兼容版本说明 - 3.2 respond_with / Class-等级respond_to)
respond_with and the corresponding class-level respond_to have been moved to the responders gem. Add gem 'responders', '~> 2.0' to your Gemfile to use it:
我的 :new 和 :create 代码现在
def new
@group = Group.new()
authorize @group
respond_with @group
end
def create
@group = Group.new(group_params)
respond_to do |format|
if @group.save #remove ? here
format.html { redirect_to groups_path }
format.js
else
format.html { redirect_to new_group_path }
format.js
end
end
end
:new.js 被正确处理
Started GET "/groups/new.js?_=1446101853822" for ::1 at 2015-10-29 07:57:40 +0100
Processing by GroupsController#new as JS
...
Rendered groups/_new_modal_content.html.erb (15.8ms)
Rendered groups/new.js.erb (23.6ms)
Completed 200 OK in 84ms (Views: 65.7ms | ActiveRecord: 3.7ms)
但是 :create 仍然引发同样的错误
Started POST "/groups" for ::1 at 2015-10-29 07:57:48 +0100
Processing by GroupsController#create as JS
...
Rendered groups/create.js.erb (0.4ms)
Completed 500 Internal Server Error in 71ms (Views: 31.6ms | ActiveRecord: 21.2ms)
AbstractController::DoubleRenderError - Render and/or redirect were called multiple times in this action. Please...
AbstractController::DoubleRenderError - Render and/or redirect were
called multiple times in this action
您应该将 create
操作更改为以下
def create
@group = Group.new(company_id: current_user.company_id, name: params[:name] )
respond_to do |format|
if @group.save #remove ? here
format.html { redirect_to groups_path, notice: 'Group was successfully created.'}
format.js
else
format.html { redirect_to new_group_path }
format.js
end
end
end
此外,由于您正在使用 Rails 4,因此您应该使用 强参数.
private
def group_params
params.require(:group).permit(:name).merge(company_id: current_user.comapany_id)
end
并改变
@group = Group.new(company_id: current_user.company_id, name: params[:name] )
到
@group = Group.new(group_params)
如问题评论中所述,action的代码没有问题
但是,after_filter 之一正在调用 render/redirect_to,这会导致 AbstractController::DoubleRenderError
错误。
对于作者的问题,似乎来自Pundit after_filters。
一种可能的解决方案是将这些过滤器用作 before_filters 而不是 after_filter。事实上,当 before_filter 调用 render 或 redirect_to 时,不会执行操作代码,并且不可能得到 AbstractController::DoubleRenderError
错误。
我正在通过 Ajax 请求创建组记录,并收到此错误(在这两种情况下,@group 有效或无效)
Started POST "/groups" for ::1 at 2015-10-28 17:47:08 +0100
Processing by GroupsController#create as JS
AbstractController::DoubleRenderError - Render and/or redirect were called multiple times in this action. Please.....
我不明白为什么,因为重定向和呈现不在同一个块中...
这是我的控制器
class GroupsController < ApplicationController respond_to:html,:js
def create
@group = Group.new(company_id: current_user.company_id, name: params[:name] )
if @group.save?
respond_to do |format|
format.html { redirect_to groups_path, notice: 'Group was successfully created.'}
format.js
end
else
respond_to do |format|
format.html { redirect_to new_group_path }
format.js
end
end
end
...
错误似乎是在尝试渲染 create.js
时发生的 Rendered groups/create.js.erb (6.5ms)
Completed 500 Internal Server Error in 48784ms (Views: 46.2ms | ActiveRecord: 4.7ms)
这是一个相当标准的 .js.erb 文件
<% if @group.errors.blank? -%>
$('#groupModal').modal('hide');
<% else %>
$( "#modalGroupAlert" ).removeClass('alert-info');
$( "#modalGroupAlert" ).addClass('alert-danger');
$( "#modalGroupAlert span" ).replaceWith( "<span><%= nicer_display_errors(@group.errors) %></span>" );
$( "#modalGroupAlert" ).show();
<% end %>
这是怎么回事?为什么?感谢反馈
更新 1 =======
根据 Pavan 的评论,我更新了创建代码,并且还添加了响应程序 gem(rails 版本 4.2.4:不兼容版本说明 - 3.2 respond_with / Class-等级respond_to)
respond_with and the corresponding class-level respond_to have been moved to the responders gem. Add gem 'responders', '~> 2.0' to your Gemfile to use it:
我的 :new 和 :create 代码现在
def new
@group = Group.new()
authorize @group
respond_with @group
end
def create
@group = Group.new(group_params)
respond_to do |format|
if @group.save #remove ? here
format.html { redirect_to groups_path }
format.js
else
format.html { redirect_to new_group_path }
format.js
end
end
end
:new.js 被正确处理
Started GET "/groups/new.js?_=1446101853822" for ::1 at 2015-10-29 07:57:40 +0100
Processing by GroupsController#new as JS
...
Rendered groups/_new_modal_content.html.erb (15.8ms)
Rendered groups/new.js.erb (23.6ms)
Completed 200 OK in 84ms (Views: 65.7ms | ActiveRecord: 3.7ms)
但是 :create 仍然引发同样的错误
Started POST "/groups" for ::1 at 2015-10-29 07:57:48 +0100
Processing by GroupsController#create as JS
...
Rendered groups/create.js.erb (0.4ms)
Completed 500 Internal Server Error in 71ms (Views: 31.6ms | ActiveRecord: 21.2ms)
AbstractController::DoubleRenderError - Render and/or redirect were called multiple times in this action. Please...
AbstractController::DoubleRenderError - Render and/or redirect were called multiple times in this action
您应该将 create
操作更改为以下
def create
@group = Group.new(company_id: current_user.company_id, name: params[:name] )
respond_to do |format|
if @group.save #remove ? here
format.html { redirect_to groups_path, notice: 'Group was successfully created.'}
format.js
else
format.html { redirect_to new_group_path }
format.js
end
end
end
此外,由于您正在使用 Rails 4,因此您应该使用 强参数.
private
def group_params
params.require(:group).permit(:name).merge(company_id: current_user.comapany_id)
end
并改变
@group = Group.new(company_id: current_user.company_id, name: params[:name] )
到
@group = Group.new(group_params)
如问题评论中所述,action的代码没有问题
但是,after_filter 之一正在调用 render/redirect_to,这会导致 AbstractController::DoubleRenderError
错误。
对于作者的问题,似乎来自Pundit after_filters。
一种可能的解决方案是将这些过滤器用作 before_filters 而不是 after_filter。事实上,当 before_filter 调用 render 或 redirect_to 时,不会执行操作代码,并且不可能得到 AbstractController::DoubleRenderError
错误。