远程真实形式上的活动存储。无效的真实性错误和错误的控制器格式
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
将我的应用程序升级到 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