远程真实形式上的活动存储。无效的真实性错误和错误的控制器格式

Active Storage on a remote true form. Invalid Authenticity error and wrong controller format

将我的应用程序升级到 Rails 5.2 后,我抽出时间研究了 Active Storage。按照指南,我已经安装了它并且 运行 进行了必要的迁移。

在我的用户模型上,我想按照此处的示例附加头像:Edge Guide for Active Storage

我在提交表单时收到的错误是 ActionController::InvalidAuthenticityToken

<%= form_for @user, remote: true do |f| %>
  <%# Other user fields redacted %>

  <div class="form-group">
    <%= f.label :avatar %>
    <%= f.file_field :avatar %>
  </div>

  <%= f.submit "Save", remote: true %>

<% end %>

我将 form_for 更改为包含 authenticity_token: true,如下所示:

<%= form_for @user, remote: true, authenticity_token: true do |f| %>

这消除了我的真实性错误并将文件插入到我的数据库中,但是这导致了未知格式错误,因为它使用 html 而不是 js 路由到我的控制器。

日志:

Started PATCH "/users/22" for 127.0.0.1 at 2018-11-07 13:36:22 +0000
Processing by UsersController#update as HTML

Disk Storage (5.7ms) Uploaded file to key: aJQ3m2skk8zkHguqvhjV6tNk (checksum: 7w6T1YJX2LNIU9oPxG038w==)
ActiveStorage::Blob Create (23.6ms)  INSERT INTO `active_storage_blobs` (`key`, `filename`, `content_type`, `metadata`, `byte_size`, `checksum`, `created_at`) VALUES ('aJQ3m2skk8zkHguqvhjV6tNk', 'Dq3gtJjU0AAbdIj.jpg-large.jpeg', 'image/jpeg', '{\"identified\":true}', 50642, '7w6T1YJX2LNIU9oPxG038w==', '2018-11-07 13:36:22')
ActiveStorage::Attachment Create (3.4ms)  INSERT INTO `active_storage_attachments` (`name`, `record_type`, `record_id`, `blob_id`, `created_at`) VALUES ('avatar', 'User', 22, 1, '2018-11-07 13:36:22')
 (9.4ms)  ROLLBACK
Completed 406 Not Acceptable in 630ms (ActiveRecord: 93.1ms)

ActionController::UnknownFormat (ActionController::UnknownFormat):

用户#更新

def update
  respond_to do |format|

    if @user.update(user_params)
      flash.now[:notice] = 'User saved successfully!'
      format.js do
        @users = User.all
      end
    else
      flash.now[:alert] = @user.errors.full_messages.to_sentence
      format.js do
        @users = User.all
        render layout: false, content_type: 'text/javascript'
      end
    end

  end
end

关于为什么将其作为 HTML 而不是 JS 提交的任何想法?

编辑:表单标记

<form class="edit_user" id="edit_user_22" enctype="multipart/form-data" action="/users/22" accept-charset="UTF-8" data-remote="true" method="post">

经过多次试验和错误后,使用 Active Storage 的直接上传功能才得以实现。请允许我解释一下我的发现:

remote: true, multipart: true一起玩的不好。有关详细信息,请参阅此 stack overflow post。本质上,您需要使用 jQuery 或 gem 来远程提交文件。

关注此 edgeguides post(直接上传)。好像当您单击提交时;直接上传将捕获提交事件并将文件直接提交到云服务器(或在我的开发案例中为本地服务器)。然后它将在表单提交中使用该图像的 reference,而不是提交实际图像。

这击中了我的 Users#update 使用 JS 并成功附加了头像。

也在过渡到 Active Storage 并卡在这里。 但是(我记得)在我以前的实现中,我使用 github/jQuery-File-Upload 我解决了(事实证明)同样的问题:

Rails.fire($("#form_id")[0], 'submit');

这是一个 rails-ujs 方法我从这个 Q/A: /with-rails-ujs-how-to-submit-a-remote-form-from-a-function

正如我现在所了解的那样:

The event — submit — is not raised when calling the form.submit() method directly, — MDN:
https://developer.mozilla.org/en-US/docs/Web/Events/submit
https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit
https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript