Rails respond_to redirect not working
在我的Rails应用程序中,创建控制器中的响应块没有在成功保存时重定向…我相信这是一个简单的解决方案,但是我对Rails没有经验,这是我第一次遇到这个问题。
窗体设置为:remote=>true,控制器如下…
1 2 3 4 5 6 7 8 9 10 11 12 13 | def create @store = current_user.stores.new(store_params) respond_to do |format| if @store.save format.html { redirect_to root_path } else format.html { flash[:alert] ="Save failed! #{@store.errors.full_messages.join(";")}" render"new" } format.js {} end end end |
在主题上,条件的其他部分的代码也不会运行,除了
我正在使用Rails 4.2.5。有人能帮助我理解为什么重定向和警报不起作用吗?谢谢您!
编辑以显示解决方案基于Rich的回答,我提出了以下解决方案:
控制器:
1 2 3 4 5 6 7 8 9 10 11 12 13 | def create @store = current_user.stores.new(store_params) flash.now[:alert] ="Save failed! #{@store.errors.full_messages.join(";")}" unless @store.save respond_to do |format| format.js end if @store.save flash[:notice] ="New store created" end end |
J.S.Erb
1 2 3 4 5 6 | <% if flash.now[:alert] %> $("#alert_holder").empty(); $("#alert_holder").append("<%= j flash.now[:alert] %>"); <% else %> window.location.href="<%= root_url %>"; <% end %> |
请注意,我需要在重定向URL周围添加引号。
表单成功后,页面重定向到根目录。失败时,错误消息将闪烁,但表单不会刷新-用户输入的任何答案都将保留。
Ajax是javascript,因此将调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | def create @store = current_user.stores.new store_params respond_to do |format| if @store.save format.js format.html { redirect_to root_path } else format.js format.html { flash[:alert] ="Save failed! #{@store.errors.full_messages.join(";")}" render"new" } end end end |
如果您不想让
阿贾克斯
您需要注意以下几点:
- Ajax cannot"redirect" (on its own)
- Ajax will be treated as
JS in your Rails controller- You have to"hack" the flash to get it working through
JS
如果您没有使用Ajax的经验,简单的解释是它是一个"伪请求";它发送一个HTTP请求而不必重新加载浏览器。
Ajax的模式很简单:
除非用JavaScript解析响应,否则不能通过Ajax"重定向"。正如Ajax首字母缩略词(Asynchronous javascript和XML)所暗示的,响应应该是XML(即没有功能)。
——
要回答您的问题,您需要使用
1 2 3 4 5 6 7 8 9 | def create @store = current_user.stores.new store_params flash.now[:alert] ="Save failed! #{@store.errors.full_messages.join(";")}" unless @store.save respond_to do |format| format.js format.html end end |
这样你就可以打电话给…
1 2 3 | #app/views/stores/create.js.erb <% if flash.now[:alert] %> alert("<%=j flash.now[:alert] %>"); <% end %> window.location.href = <%= root_url %>; |
裁判
您的新代码可以改进一点:
1 2 3 4 5 6 7 8 9 10 11 12 13 | def create @store = current_user.stores.new store_params if @store.save flash[:notice] ="New store created" else flash.now[:alert] ="Save failed! #{@store.errors.full_messages.join(";")}" end respond_to do |format| format.js end end |
如果你想更多地增加你的代码,你可以看看
1 2 3 4 5 6 7 8 9 | #app/controllers/stores_controller.rb class StoresController < ApplicationController respond_to :js, only: :create def create @store = ... respond_with @store if @store.save end end |
如果您的表单中有
2种选择:
- 默认为正常形式提交(通过删除
remote: true ) - 通过添加
format.js 加载另一个js.erb文件,就像在else子句中一样,然后通过一些javascript在那里进行错误处理。