【问题标题】:Rails respond_to redirect not workingRails respond_to 重定向不起作用
【发布时间】:2016-05-06 18:29:17
【问题描述】:

我的 Rails 应用程序中创建控制器中的 respond_to 块在成功保存时没有重定向...我确信这是一个简单的解决方案,但我对 Rails 缺乏经验,这是我第一次遇到这个问题。

表单设置为:remote => true,控制器如下...

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

当我谈到这个主题时,条件的 else 部分的代码也不会运行,除了 format.js {},它运行我的 create.js 中的代码.erb 文件(暂时是一个警报)。

我正在使用 Rails 4.2.5。有人可以帮我理解为什么重定向和警报不起作用吗?谢谢!

编辑以显示解决方案 根据 Rich 的回答,这是我想出的解决方案:

控制器:

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

create.js.erb

<% if flash.now[:alert] %>
    $("#alert_holder").empty();
    $("#alert_holder").append("<%= j flash.now[:alert] %>");
<% else %>
    window.location.href = "<%= root_url %>";
<% end %>

请注意,我需要在重定向 url 周围添加引号。

表单成功后,页面重定向到根目录。失败时,错误消息会闪烁,但表单不会刷新 - 用户输入的任何答案都会保留。

【问题讨论】:

    标签: ruby-on-rails ajax respond-to


    【解决方案1】:

    remote: true 是一个ajax 请求。

    Ajax 是 javascript,因此会调用 format.js 方法:

    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
    

    format.js 方法将调用 /app/views/[:controller]/[:action].js.erb 文件,该文件将触发您在其中的任何 JS。

    如果您不想让 js 格式处理响应,则必须取消 respond_to 并只保留您想要返回的内容(redirect_to 不起作用) .


    Ajax

    您需要了解以下几个规定:

    • Ajax 无法“重定向”(单独)
    • Ajax 在 Rails 控制器中将被视为 JS
    • 您必须“破解”闪存才能使其通过JS

    如果你没有 Ajax 的经验,简单的解释是它是一个“伪请求”;它无需重新加载浏览器即可发送 HTTP 请求。

    Ajax 的模式很简单:Ajax request &gt; server &gt; Ajax response

    除非您使用 javascript 解析响应,否则您不能通过 Ajax “重定向”。正如 Ajax 首字母缩写词(Asynchronous Javascript And XML)所暗示的,响应应该是 XML(IE 没有功能)。

    --

    要回答您的问题,您需要将flash.now 用于“flash”消息,并使用您的.js.erb 文件处理响应:

    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
    

    这将允许您调用...

    #app/views/stores/create.js.erb
    <% if flash.now[:alert] %> alert("<%=j flash.now[:alert] %>"); <% end %>
    window.location.href = <%= root_url %>;
    

    Ref


    你的新代码可以稍微改进一下:

    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
    

    如果您想进一步提升您的代码 DRY,您需要查看 responders gem:

    #app/controllers/stores_controller.rb
    class StoresController < ApplicationController
       respond_to :js, only: :create
    
       def create
          @store = ...
          respond_with @store if @store.save
       end
    end
    

    【讨论】:

    • 这真是太棒了,我自己不会想出来的。感谢您为 Rails 新手提供指导。
    • 我已经编辑了我的问题,以显示我根据您的指导得出的答案。我不得不调整一些东西,但效果很好。
    【解决方案2】:

    如果您的表单中有remote: true,控制器检测到的格式将是format.js,这在您成功的@store.save 部分中不存在。

    2 个选项:

    • 默认为普通表单提交(通过删除remote: true
    • 通过添加 format.js 来加载另一个 js.erb 文件,就像在 else 子句中一样,然后通过一些 javascript 进行错误处理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-20
      • 1970-01-01
      • 2014-02-05
      • 2017-10-08
      相关资源
      最近更新 更多