質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.48%

link_toでdeleteメソッドが飛ばせない(Rails6+webpacker)

受付中

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 3,979

前提・実現したいこと

Railsで簡単なブログの作成をしております。
現在投稿した記事の削除機能の実装を試みております。

発生している問題・エラーメッセージ

link_toヘルパーでdestroyアクションに飛ばそうとしているのですが、
なぜかhttpメソッドが「GET」と判定されてしまい、下記エラーが発生します。

Unknown action
The action 'show' could not be found for ArticlesController

該当のソースコード

[index.html.erb]
<% @articles.each do |article| %>
 <%= article.created_at.strftime('%Y/%m/%d') %>  |  <%= article.title %> <br>
 <%= article.content %><br>
 <% if user_signed_in? %>
 <%= link_to 'edit', edit_article_path(article) %>
 <%= link_to 'delete', article_path(article), method: :delete %> ★ここです★
<% end %>
[routes.rb]
Rails.application.routes.draw do
  devise_for :users, controllers: { sessions: 'users/sessions'}

  devise_scope :user do
   get '/users/sign_out' => 'devise/sessions#destroy'
  end

 root 'articles#index'

 resources :users
 resources :articles
end


コンソールでルーティングの確認

article GET    /articles/:id(.:format)    articles#show
        PATCH  /articles/:id(.:format)    articles#update
        PUT    /articles/:id(.:format)    articles#update
        DELETE /articles/:id(.:format)    articles#destroy                                                                         
[articles_controller.rb]
class ArticlesController < ApplicationController
 before_action :user
 before_action :article, only:[:index, :edit, :update, :destroy]

※下記関係するアクションのみ記入

def index
 if @user
 @articles = @user.articles.order(created_at: :desc)
end

def destroy
 @article.destroy
 flash[:success] = "Article deleted"
 redirect_to root_url
end

 private
  def article
   @article = Article.find_by(id: params[:id])
  end

  def articles_params
   params.require(:article).permit(:title, :content)
  end

試したこと

なぜかlink_toではなく、button_toにすると記事が削除できます。
以上から削除に関するコードの記述方法に問題はないと考えております。

httpメソッドの「delete」はjavascriptを使用して送っているということまではなんとなく理解してます。layouts/application.html.erbファイルで、head部分に下記記入してます。

[layouts/application.html.erb]
<head>
  <title>SampleBlog</title>
  <%= csrf_meta_tags %>
  <%= csp_meta_tag %>

  <%= stylesheet_pack_tag 'application', media: 'all' %>
  <%= javascript_pack_tag 'application' %>
</head>


app/javascript/packs/application.js に下記記載

[app/javascript/packs/application.js]
require("@rails/ujs").start()
require("@rails/activestorage").start()
require("channels")
require("jquery")

import 'bootstrap'
import '../src/application.scss'
import Rails from 'rails-ujs'
Rails.start()
[package.json]
{
  "name": "sample_blog",
  "private": true,
  "dependencies": {
    "@rails/actioncable": "^6.0.0",
    "@rails/activestorage": "^6.0.0",
    "@rails/ujs": "^6.0.3-1",
    "@rails/webpacker": "4.2.2",
    "jquery": "^3.5.1",
    "popper.js": "^1.16.1",
    "turbolinks": "^5.2.0"
  },
  "version": "0.1.0",
  "devDependencies": {
    "webpack-dev-server": "^3.11.0"
  }
}

開発環境

ruby 2.7.1
rails 6.0.3

何が問題でlink_toでdeleteメソッドが飛ばせないのか全くわからない状態です。
分かる方いらっしゃれば教えていただきたいです。。。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

【追記3】

TakeshiAoyamaさんも気づかれているようですが、jquery_ujs は@rails/ujs に置き換わっているようです。

jquery を積極的に利用していないのであれば、 app/javascript/packs/application.js から、

require("jquery")

を削除した方が良いかもしれません。

参考までに Rails 6 でデフォルトで作られている当該箇所を記載します。

require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")

【追記2】

似たような記事を見つけました。

Railsの削除のルーティンがうまく行かない Unknown action The action 'show' could not be found for BlogsController - Qiita

app/assets/javascripts/application.js に

//= require jquery_ujs

を追記してみてください。

※Rails6 だとこの構成になっていないようなので別のファイルを修正する必要がありそうです。

【追記1】
Ruby on Rails チュートリアル:実例を使って Rails を学ぼうコラム 3.2. GETやその他のHTTPメソッドについてでは、以下のように書かれています。

これは、ブラウザがPATCHとDELETEをネイティブでは送信しないからです。しかし、Ruby on Railsなどの多くのWebフレームワークは、ブラウザがこれらの操作のリクエストを送信しているかのように見せかける技術 (偽装) を駆使して、PATCHとDELETEという操作を実現しています。

なのでブラウザーの開発者ツールで見ても GET でのアクセスに見えます。

問題の本質は、以下のエラーメッセージかと思います。

The action 'show' could not be found for ArticlesController

ちなみに

article GET    /articles/:id(.:format)    articles#show

に対応するメソッドは実装されていますか?

show メソッドが不要であれば、config/routes.rb でその旨を記載する必要があるかと思います。

resources :articles, :except => :show

参考: 

【問題の本質とは関係ありません。】
Getting Started with Rails — Ruby on Rails Guides の例に倣って、

<%= link_to 'delete', article_path(article), method: :delete,
               data: { confirm: 'Are you sure?' } %>

とした場合、どうなりますか?

【以下、勘違いです。】

<%= link_to 'destroy', article_path(article), method: :delete %>

では?

def destroy
 @article.destroy
 flash[:success] = "Article deleted"
 redirect_to root_url
end

と宣言されているので。

routes も以下のように articles#destroy となっていますし。

DELETE /articles/:id(.:format)    articles#destroy

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/06/07 01:30

    いただいたリンクのページは私も見ております。application.jsの書き方がRails5とRails6で変わっているようで、Rails6では「jquery_ujs」は削れというような記述のウェブサイトもありました。
    https://paulownia.hatenablog.com/entry/2020/01/01/202628

    とりあえず頭が働くなってきたのでまた明日チャレンジしてみます。。
    お付き合いいただきありがとうございました。。

    キャンセル

  • 2020/06/07 01:32

    色々、調べている内に jquery_ujs は、@rails/ujs に置き換わったようです。

    jquery を積極的に使用していないのなら、

    require("jquery")

    を削除した方が良いかもしれません。

    キャンセル

  • 2020/06/09 11:59

    require("jquery")外したのですが、結果は変わりませんでした・・
    @rails/ujs読み込み方についてもう少し勉強してみようと思います。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.48%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る