Rails表单提交未在后台进行

时间:2019-01-21 06:11:02

标签: ruby-on-rails ajax

我有一个Rails 5.2应用程序,我正在使用form_with生成此HTML:

<form id="post-0" class="" action="/posts.js" accept-charset="UTF-8" data-remote="true" method="post">

该表单已成功提交给PostController的create操作。

  def create
    @post = current_user.account.posts.new(post_params)
    respond_to do |format|
      if @post.save
        format.html { redirect_to posts_path, notice: 'Post added.' }
        format.js { render :create, status: :created }
      else
        format.html { render :index }
        format.js { render :create, status: :unprocessable_entity }
      end
    end
  end

然后呈现JS视图:
app / views / posts / create.js.erb

alert('created');

但是,在我的浏览器中,我实际上被重定向到了http://localhost:3000/posts.js,其中显示了JavaScript代码。意思是,表单提交不是似乎是在后台进行的。

我本来希望仍然停留在表单所在的页面上,并且出现一个Javascript Alert,提示“已创建”。

我错过了一些愚蠢的事情吗?在我看来,一定是form_with我做错了。

我尝试将其交换为form_for @post, remote: true, format: :js do ...,但是存在相同的问题。

这时,我无法确定问题出在显示表单的View还是Controller的create操作中。控制器正在渲染create.js.erb,显示的URL为http://localhost:3000/posts.js,这似乎表明这是视图中的表单问题。

此应用为Rails 5.2。我不确定是否相关,但是我已经删除了Webpacker的Asset Pipeline,我安装了rails-ujs(因为在这些link_to中显示了确认对话框预期的链接<%= link_to('Destroy', user, method: :delete, data: { confirm: 'Are you sure?' }) %>

3 个答案:

答案 0 :(得分:1)

由于多种原因,表单提交可以在本地进行(即,不是远程的)。

使用 form_with 时可能会导致本地提交的一些常见原因包括:

  

本地:true

local 属性对于form_with是可选的。如果未提供,form_with默认设置为local: false

  • true会将表单设置为本地提交(标准表单提交),而不是远程/异步提交。

  • false会将表单设置为远程/异步提交。

false以外的任何值(包括:false,它是符号而不是 boolean )都将被解释为{{ 1}}(即在本地提交)。

  

JavaScript触发的表单提交

尽管将true属性的设置设置为应触发远程/异步表单提交的内容,但是如果您通过Javascript触发表单local事件,则该表单可能仍在本地提交

在上述示例中,submit使用生成的HTML是预期的,因此在这种情况下,提供给form_with的属性不是问题。

如果使用JavaScript提交表单,则可能是问题所在。例如,即使在表单上使用form_with,此javascript也会出现问题:

data-remote="true"

这将提交表单,但doesn't raise a submit eventdocument.getElementById('form-0').submit(); 通过rails-ujs事件处理程序进行拦截。

使用Rails Unobtrusive Javascript Adapter

要使表单提交由javascript(无论您使用的是jQuery,Stimulus JS还是其他任何一种)触发,您需要使用rails-ujs(或jquery-ujs)会为您拦截的机制

Rails在onsubmit中提供了Rails.fire自定义javascript事件包装器,可以这样使用:

rails-ujs

答案 1 :(得分:0)

您犯了一个非常基本的错误。使用ajax不能使用format.js。此Ruby模块用于重定向页面。相反,您应该使用render json: { status: 200}

答案 2 :(得分:-1)

在Upwork上看到了您的工作。无需为此花费100美元!

<%= form_with url: content_export_path, method: :post, id: 'ce_form1', data: { remote: true } %>

查看remote:true声明的位置...(在数据哈希中)

让我知道这是否可行。