Ruby on Rails中的link_to删除方法无法正常工作

24

我正在尝试使用以下代码删除一个帖子:

<%= link_to 'Destroy', post, :method => :delete, :onclick => "return confirm('Are you sure you want to delete this post?')" %>

以下代码可以正常工作,而上述代码会将我重定向回帖子 (posts/:id)

<%= button_to 'Destroy', post, method: :delete, :onclick => "return confirm('Are you sure you want to delete this post?')" %>

在这种情况下,是否可能使link_to的行为与button_to相同?

编辑:销毁控制器函数

  def destroy
    @post = Post.find(params[:id])
    @post.destroy

    respond_to do |format|
      format.html { redirect_to posts_url }
      format.json { head :no_content }
    end
  end

当我点击销毁按钮时,记录日志:

Started GET "/posts/14" for 127.0.0.1 at 2012-10-21 15:38:28 +0300
Processing by PostsController#show as HTML
  Parameters: {"id"=>"14"}
  Post Load (0.4ms)  SELECT `posts`.* FROM `posts` WHERE `posts`.`id` = 14 LIMIT 1
  Rendered posts/show.html.erb within layouts/application (0.6ms)
  User Load (0.4ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
Completed 200 OK in 7ms (Views: 5.4ms | ActiveRecord: 0.8ms)
[2012-10-21 15:38:28] WARN  Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true

路由:

  devise_for :users

  resources :users

  resources :posts

  match '/about' => 'about#index'

  # You can have the root of your site routed with "root"
  # just remember to delete public/index.html.
  root :to => 'index#index'

  # See how all your routes lay out with "rake routes"

  # This is a legacy wild controller route that's not recommended for RESTful applications.
  # Note: This route will make all actions in every controller accessible via GET requests.
  # match ':controller(/:action(/:id))(.:format)'
  match '*a', :to => 'error#routing'

3
你能确认一下你的Gemfile中是否有jquery-rails这个gem包?如果有的话,能否通过Web检查器确认它是否被发送到客户端浏览器中。 - adimitri
是这样的,当我创建了Rails项目时,我从app.js中删除了//=行,这就导致了问题...谢谢! - stergosz
10个回答

33

您必须添加

//= require jquery
//= require jquery_ujs
在javascripts/application.js文件中。 其次,在布局文件中检查。
javascript_include_tag "application"

是否包含?

希望这可以帮助。


1
非常感谢。我错过了//= require jquery_ujs。 - Sarah
升级到5.1的Rails指南表示,rails_ujs现在已经包含在Rails中。但是,尽管您可以从Gemfile中删除它,但无法从这里删除它。啊!浪费了几个小时才找到这个问题。 - chetstone

15

解决方案:

在创建项目时,我已经将这段代码从application.js中注释掉了。

// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
// GO AFTER THE REQUIRES BELOW.
//
//= require jquery
//= require jquery_ujs
//= require_tree .

所以重新添加它解决了问题。


2
要明确的是,如果这不是显而易见的话,似乎require jquery_ujs是重要的部分。 - Jason Swett
3
今天我加回了jquery_ujs,问题完全解决了。7年过去了,这仍然是正确的答案。根据文档,jquery_ujs的一个功能是允许您“从超链接中进行非GET请求”。如果没有它,DELETE请求会变成GET请求。 - Daniel Nalbach

6
首先尝试检查日志中生成的HTTP post方法。如果是“Get”,无论路由等如何,它都不会触发控制器中的删除操作。它必须是一个HTTP删除方法。
在包括Rails 6+在内的最新版本中,包括jquery UJS等不是选项/易于使用的情况下,您应该使用https://apidock.com/rails/ActionView/Helpers/UrlHelper/button_to


6
你在你的布局文件中包含了这行代码吗?
<%= javascript_include_tag "application" %>

默认情况下,这是在布局文件中的。 - stergosz
如果您将 "application" 替换为 ":defaults",会有什么帮助吗? <%= javascript_include_tag :defaults %> - Nanego
似乎也不起作用...我的问题不在于警告,而是它无法删除帖子...只是为了确保... - stergosz

3

如果要使用带有:delete方法的link_to,必须确保启用了javascript:

请注意,如果用户禁用了JavaScript,则请求将回退到使用GET。

文档中所示。

如果您不想依赖javascript,可以使用button_to代替link_to


3

不使用jQuery也可以实现可用的link_to

我找到了一个最佳的过程,可以在Ruby on Rails中实现可用的删除链接而不需要使用jQuery!我们需要处理以下三个方面:

  1. articles_controller.rb中添加destroy方法
  2. routes.rb设置
  3. LINK_TO标签

让我们开始吧...

在articles_controller.rb中添加destroy方法

首先,我们将在articles_controller.rb中添加def destroy ... end,让我们打开:

# app/controllers/articles_controller.rb

  def destroy
    @article = Article.find(params[:id])
    @article.destroy
    params[:id] = nil
    flash[:notice] = "Art has been deleted"
    redirect_to :action => :index
  end

在第一行,我们调用了一个变量“@article”,该变量将从数据库中查找并选择文章的ID参数,然后在rails控制台上执行删除操作。

在第二行,@article变量将在控制台中执行销毁命令。

在第三行:id参数将被删除。

在第四行,应用程序页面将闪现通知“Art has been deleted”,并且在控制台中显示未在数据库中找到任何内容。

在第五行,在销毁过程完成后,我们将被重定向到文章索引页面。

这是给出销毁命令的主要因素,并使link_to工作。

设置routes.rb

但是等等 我们需要两个用于销毁页面的路由:

  1. GET协议设置
  2. DELETE协议设置

在路由中添加:

  resources :articles, except: [:destroy] # this will add all get request links automatically except destroy link

  post '/articles/new' => 'articles#create'
  post '/articles/:id' => 'articles#update'
  post '/articles/:id/edit' => 'articles#update' # this 3 lines are needed for other forms purpose

  # we need this 2 lines for our delete link_to setup
  delete 'articles/:id/delete' => 'articles#destroy', as: 'articles_delete'
  get '/articles/:id/delete' => 'articles#destroy'
  

在这里

  1. 倒数第二行声明了DELETE方法,

    • 'articles/:id/delete'是每篇文章中的链接结构,将作为post链接标签(在HTML中称为锚标签)。
    • '=>'指向链接结构的控制器标签,即'articles#destroy'
    • 然后我们通过将**设置为'articles_delete'**来定义路径文本,我们将在link_to标签中使用'articles_delete_path'或'articles_delete_url'。

然后

  1. 在最后一行,我们定义了删除链接的get请求,这将给我们一个工作链接,如“https://2haas.com/articles/1/delete”,除了“/articles/1/destroy”之外,这意味着我们可以从这2种方法设置中自定义我们的删除链接,加入更多附加信息。

最后想要的delete输出

所需的link_to标签

我们可以使用这个标签来获取正确的删除link_to标签。

<%= link_to 'Delete Article', articles_delete_path, method: :delete %>
<%= link_to 'Delete Article', articles_delete_url, method: :delete %>

<% obj.each do |post| %>
<%= link_to 'Delete Article', articles_delete_path(post), method: :delete %>
<% end %>

除了jQuery之外,这就完成了

感谢您认真阅读此答案!

编程愉快!


1
这是Rails的方式: <%= link_to 'Destroy', post, confirm: 'Are you sure?', method: :delete %> 如果帖子没有被删除,那么问题就出在你的控制器上。你确定你已经正确地实现了#destroy操作吗?你在服务器日志中得到的输出是什么?
更新:将您的操作更改为:
def destroy
  @post = Post.find(params[:id])

  respond_to do |format|
    if @post.destroy
      format.html { redirect_to posts_url }
      format.json { head :no_content }
    else
      format.html # do something here
      format.json { head :no_content }
    end
  end
end

更新了我的答案。如果这样还不起作用,您应该发布服务器日志。 - Agis
仍然不起作用...上面的link_to代码有两个问题...首先,确认框没有显示出来,其次我不确定link_to是否能够到达销毁操作...它似乎只是跳转到了帖子本身...-编辑:还有,在dev日志中没有任何奇怪的东西...它只是进行了GET请求。 - stergosz
它不应该执行一个get请求。你能发布你的日志吗?还有你的routes.rb文件? - Agis
更新了问题,添加了日志链接点击和路由... 删除了format.json但仍然没有成功。 - stergosz

0

检查空格。

我检查了这里的所有评论。 所有的包含都设置正确。 但是我注意到删除文章不起作用,而删除评论会起作用。 在重写一些代码并在此处检查后,我发现编辑器中看起来完全相同的两个文件,但一个版本可以工作,而另一个则不能工作!

curry-blog/app/views/articles/index.html.erb:

<h1>Listing Articles</h1>
<%= link_to 'New article', new_article_path %>
<table>
  <tr>
    <th>Title</th>
    <th>Text</th>
    <th colspan="3"></th>
  </tr>
 
  <% @articles.each do |article| %>
    <tr>
      <td><%= article.title %></td>
      <td><%= article.text %></td>
      <td><%= link_to 'Show', article_path(article) %></td>
      <td><%= link_to 'Edit', edit_article_path(article) %></td>
      <td><%= link_to 'Delete', article_path(article),
              method: :delete,
              data: { confirm: 'Are you sure?' } %></td>        
    </tr>
  <% end %>
</table>

然而,通过使用xxdiff查看文件,我发现在一个版本中只使用了制表符,而另一个版本也使用了空格。很可能是从教程中复制粘贴代码导致的。因此,用制表符替换空格解决了问题。

0

请确保参数后面没有空格

def destroy
        @post = Post.find(params[:id])
        @post.destroy
        redirect_to posts_path, :notice => "Your post has been deleted successfully."
end

-1

对我来说它完美地工作了, <%= button_to '删除', article_path(article), method: :delete %>


OP专门询问“link_to”方法。 - Leland Reardon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接