繁体   English   中英

Ruby On Rails 7 - 删除方法不起作用

[英]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 版本中被移入 RailsHotwire 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_toredirect_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
  • 添加 gem importmap-rails
  • 安装 importmap 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM