Ruby on rails Rails对重定向不起作用作出响应

Ruby on rails Rails对重定向不起作用作出响应,ruby-on-rails,ajax,respond-to,Ruby On Rails,Ajax,Respond To,成功保存时,my Rails应用程序中创建控制器中的respond_to block未重定向。。。我相信这是一个简单的解决方案,但我对Rails缺乏经验,这是我第一次遇到这个问题 表单设置为:remote=>true,控制器如下所示 def create @store = current_user.stores.new(store_params) respond_to do |format| if @store.save format.h

成功保存时,my Rails应用程序中创建控制器中的respond_to block未重定向。。。我相信这是一个简单的解决方案,但我对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 %>

$(“警报持有者”).empty();
$(“#警报持有人”)。追加(“”);
window.location.href=“”;
注意,我需要在重定向url周围添加引号


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

如果表单中有
remote:true
,则控制器检测到的格式将是format.js,它不会出现在成功的
@store.save
部分中

2种选择:

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

    • 远程:true是一个请求

      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
      格式处理响应,那么您必须取消
      response\u to
      ,只返回您想要的内容(
      重定向到
      将不起作用)


      Ajax

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

      • Ajax不能“重定向”(单独重定向)
      • 在Rails控制器中,Ajax将被视为
        JS
      • 你必须“破解”flash才能让它通过
        JS
      如果您没有使用Ajax的经验,简单的解释是这是一个“伪请求”;它发送HTTP请求而不必重新加载浏览器

      Ajax的模式很简单:
      Ajax请求>服务器>Ajax响应

      除非使用javascript解析响应,否则无法通过Ajax“重定向”。正如Ajax的首字母缩略词(异步Javascript和XML)所暗示的,响应应该是XML(即没有功能)

      --

      要回答您的问题,您需要使用“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 %>;
      
      如果您想更进一步地
      DRY
      up您的代码,您需要查看gem:

      #app/controllers/stores_controller.rb
      类StoresController<应用程序控制器
      回复:js,仅::create
      def创建
      @存储=。。。
      如果@store.save,则回复@store
      结束
      结束
      
      这真是太好了,我自己也不会想到这一点。感谢您为Rails新手提供指导。我已经编辑了我的问题,以显示我根据您的指导得出的答案。我不得不调整一些东西,但它工作得非常好。
      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
      
      #app/controllers/stores_controller.rb
      class StoresController < ApplicationController
         respond_to :js, only: :create
      
         def create
            @store = ...
            respond_with @store if @store.save
         end
      end