[英]Ruby On Rails 7 - Delete method not working
在我的 RoR 项目中,我的删除方法不起作用。 这很奇怪,因为它一天前还在工作,但现在它所做的一切都将我重定向到“朋友”页面。 另一件需要注意的事情是“你确定吗?”的弹出对话框。 删除以前工作的朋友时也不会出现。 我在网上阅读了一些解决方案,说明在您的 javascript 文件中放置“//= require jquery”和“//= require jquery_ujs”,但我只能在“app/assets/config”目录中找到我的 manifest.js 文件。
任何帮助将不胜感激。
index.html.erb
<% if user_signed_in? %>
<table class="table table-striped table-bordered table-hover">
<thead class="thead-dark">
<tr>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
<th>Twitter</th>
<th>User ID</th>
<th></th>
</tr>
</thead>
<tbody>
<% @friends.each do |friend| %>
<% if friend.user == current_user %>
<tr>
<td>
<%= link_to friend.first_name + " " + friend.last_name, friend, style: 'text-decoration:none' %>
</td>
<td><%= friend.email %></td>
<td><%= friend.phone %></td>
<td><%= friend.twitter %></td>
<td><%= friend.user_id %></td>
<td>
<%= link_to 'delete',
friend,
:method => :delete,
:confirm => "are you sure?",
class: "btn btn-danger btn-sm" %>
</td>
</tr>
<% end %>
<% end %>
</tbody>
</table>
<br>
<% else %>
<h1>Welcome to the Friend App</h1>
<% end %>
清单.js
//= link_tree ../images
//= link_tree ../builds
//= require jquery
//= require jquery_ujs
在 Rails 7 中,指定删除方法的“旧”方式不起作用。 我的猜测是从 rails-ujs 到 turbo 的变化是罪魁祸首。 Rails-ujs 在 5.1 版本中被移入 Rails , Hotwire Turbo 在 rails 7 中替换了它。
这就是我解决问题的方法:
路线:destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
.html.erb:
<%= link_to t('navigation.sign_out'), destroy_user_session_path, method: :delete, class: "btn btn-danger ml-3" %>
html:(注意 data-method="delete")
<a class="btn btn-danger ml-3" rel="nofollow" data-method="delete" href="/users/sign_out"><span class="translation_missing" title="translation missing: en.navigation.sign_out">Sign Out</span></a>
错误:没有路由匹配 [GET] "/users/sign_out"
用( 解决方案来源)解决了它
.html.erb:
<%= link_to t('navigation.sign_out'), destroy_user_session_path, data: { "turbo-method": :delete }, class: "btn btn-danger ml-3" %>
.html:(注意 data-turbo-method="delete")
<a data-turbo-method="delete" class="btn btn-danger ml-3" href="/users/sign_out"><span class="translation_missing" title="translation missing: en.navigation.sign_out">Sign Out</span></a>
如果您希望确认消息开箱即用,请简要说明rails 7 :
<%= link_to t('navigation.sign_out'),
destroy_user_session_path,
data: { turbo_method: :delete, turbo_confirm: 'Are you sure?' },
class: "btn btn-danger ml-3" %>
Rails 7 使用 Turbo 和刺激框架来提高前端性能。
您需要安装 turbo 和 stimulus。 在您的终端上运行以下命令:
$ rails importmap:install
$ rails turbo:install stimulus:install
确保您使用的是turbo_method
,例如:
<%= link_to "Sign Out", destroy_user_session_path, data: { turbo_method: :delete }, class: "nav-link" %>
您需要 go 到https://guides.rubyonrails.org/getting_started.html的第 7.5 节。 它解释了为什么
我们需要设置“Destroy”链接的 data-turbo-method 和 data-turbo-confirm HTML 属性。
阅读整个第 7.5 节,包括两个示例中的销毁操作。 当您单击删除按钮时,还要在控制台中保留日志并观察错误。 为避免头部拍打时刻,在销毁操作中尝试根据 rails 指南将状态添加到 redirect_to , redirect_to whatever_path, status: :see_other
这也适用于删除 object 并呈现新的时,您需要设置status:unprocessable_entity
unprocessable_entity 导致服务器回复 422。
这里的关键是确保您在Turbo的 link_to 中有turbo_method: :delete
,然后, method: :delete
将 GET 更改为删除,最后您的destroy action
在您使用 redirect_to 时具有状态以避免当/如果浏览器使用 DELETE 方法将您重定向到另一个位置时出错。
<%= link_to "Delete", friend, method: :delete, data: { turbo_method: :delete, turbo_confirm: 'Are you sure?' }, class: 'btn btn-danger' %>
您需要传递 controller 的路径,而不仅仅是 object。
<%= link_to 'delete',
friend_path(friend),
:method => :delete,
:confirm => "are you sure?",
class: "btn btn-danger btn-sm" %>
您还需要为此请求找到正确的路径,您可以执行以下操作来为朋友找到匹配的路由。
rails routes | grep friend
您也可以使用 button_to 代替 link_to
<%= button_to friend_path(friend), method: :delete do %>
Delete
<% end %>
我将我的应用程序升级到 Rails 7,但不想使用导入地图、turbo 等。所以我想出了自己的 Javascript 解决方案,用于向我的销毁链接添加确认对话框。
首先,我将所有链接都变成了buttons
,这使得触发delete
请求变得更加容易:
def link_to_destroy(object)
path = send("#{controller_name.singularize}_url", object)
button_to "Destroy", path, :method => :delete, :data => { :confirm => "Are you sure?" }, :form_class => "confirm_destroy", :class => "destroy_icon"
end
(请注意,Rails 会自动将这些按钮包装在包含delete
方法的form
标签中。我发现这些按钮的样式非常容易。我只需要更改 CSS 中的一行代码。)
这是我用来触发确认对话框的 Javascript:
function ConfirmDestroy() {
const forms = document.querySelectorAll('.confirm_destroy');
forms.forEach(form => {
form.addEventListener('submit', function(e) {
handleSubmit(form, e);
});
});
function handleSubmit(form, e) {
e.preventDefault();
let message = form.querySelector('button').dataset.confirm; // pull the actual confirmation message from the data-attribute 'confirm' to support multiple languages
if (!confirm(message)) {
return false;
}
form.submit();
}
}
document.addEventListener('DOMContentLoaded', ConfirmDestroy);
我已经在 Mac 上的最新版本的 Chrome、Safari 和 Firefox 中对其进行了测试,到目前为止还没有遇到任何问题。
这个解决方案的好处是它还支持多种语言。 实际的确认消息将简单地从confirm
数据属性中提取。 所以你可以放任何你想要的字符串或消息。
对于那些仍然有此问题的人,这里有一些其他步骤可能会有所帮助:
导轨版本:7.0.3.1
参考: Rails 7:link_to 方法::delete 不起作用
请按照以下步骤操作:
bundle add hotwire-rails
importmap-rails
rails importmap:install
rails hotwire:install
下一个代码有效:
%td= link_to t('common.destroy'), task, data: { turbo_method: :delete, turbo_confirm: t('common.confirm') }
作为附加信息,使用:
gem hamlit
gem simple_form
我遇到了同样的问题,我很困惑。 我尝试了所有方法,但一直无法销毁,日志始终显示页面呈现为 HTML 而不是 turbo stream。然后我切换到 Opera 浏览器(来自 chrome),一切都按预期工作。 有什么意义吗?
我正在使用设备,我将其更改为使用 turbo_method
= link_to "Sign out", destroy_user_session_path, method: :delete, data: { turbo_method: :delete }
虽然这会破坏 session,但它不会更新视图,我最终得到一个奇怪的 state 在这里输入图像描述
我有什么不对?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.