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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Haml

Haml(HTML abstraction markup language)は、HTML/XHTMLを効率的に記述するためのマークアップ言語および記法です。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

1回答

2109閲覧

ActionController::UrlGenerationError(いいねボタンのmethod:delete)

KotaTakahashi

総合スコア8

Haml

Haml(HTML abstraction markup language)は、HTML/XHTMLを効率的に記述するためのマークアップ言語および記法です。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2020/07/30 16:36

編集2020/07/31 03:18

解決したいこと

  • いいね機能を実装中です。その際、いいねボタンを押すと、ActionController::UrlGenerationErrorが出て、トップページを表示できなくなってしまいました。
  • method: :delet(エラー画面の指定箇所)をコメントアウトすると、「いいねしたユーザー」が正しく表示されます。ですので、javascriptの関係のエラーかと思ったのですが、javascript_pack_tagを使用しているのと、投稿削除のdeleteメソッドは正しく作動しているので、原因がわかりませんでした。
  • すみませんがどなたか分かる方いらっしゃいましたら、ご教授お願いします。

試したこと

  • 【tweets > index.heml.haml】= button_to 'いいねを取り消す', tweet_like_path(tweet), method: :deleteの部分を = button_to 'いいねを取り消す', tweet_like_path(tweet,like), method: :deleteに変更

→NAME ERROR undefined local variable or method `like'

  • 【tweets_controller.rb】の
def index @tweets = Tweet.includes(:user).order("created_at DESC") @like = Like.new end

↓↓↓を下記に変更↓↓↓

def index @tweets = Tweet.includes(:user,:like).order("created_at DESC") @like = Like.new end

→ActiveRecord::AssociationNotFoundErrorになってしまいました。

環境

rails 6.0.0
"haml-rails", ">= 1.0", '<= 2.0.1'
'pg', '>= 0.18', '< 2.0'

参考記事

https://qiita.com/nojinoji/items/2c66499848d882c31ffa

関連のする箇所

エラー画面

イメージ説明

実行時のターミナル

terminal

1Started GET "/tweets" for ::1 at 2020-07-30 23:55:11 +0900 2Processing by TweetsController#index as HTML 3 Rendering tweets/index.html.haml within layouts/application 4 Tweet Load (1.0ms) SELECT "tweets".* FROM "tweets" ORDER BY created_at DESC 5 ↳ app/views/tweets/index.html.haml:3 6 User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 [["id", 1]] 7 ↳ app/views/tweets/index.html.haml:3 8 User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]] 9 ↳ app/views/tweets/_tweet.html.haml:9 10 Tag Load (0.7ms) SELECT "tags".* FROM "tags" INNER JOIN "tweet_tag_relations" ON "tags"."id" = "tweet_tag_relations"."tag_id" WHERE "tweet_tag_relations"."tweet_id" = $1 [["tweet_id", 7]] 11 ↳ app/views/tweets/_tweet.html.haml:19 12 Like Exists? (0.6ms) SELECT 1 AS one FROM "likes" WHERE "likes"."user_id" = $1 AND "likes"."tweet_id" = $2 LIMIT $3 [["user_id", 1], ["tweet_id", 7], ["LIMIT", 1]] 13 ↳ app/models/user.rb:11:in `already_liked?' 14 Rendered tweets/_tweet.html.haml (Duration: 19.4ms | Allocations: 4272) 15 Rendered tweets/index.html.haml within layouts/application (Duration: 35.9ms | Allocations: 6190) 16Completed 500 Internal Server Error in 47ms (ActiveRecord: 3.3ms | Allocations: 6799) 17 18 19 20ActionView::Template::Error (No route matches {:action=>"destroy", :controller=>"likes", :tweet_id=>#<Tweet id: 7, name: nil, text: "あ", image: "f3072d14ccf044ef823aeb8538ae3ced.jpg", created_at: "2020-07-30 04:13:59", updated_at: "2020-07-30 04:13:59", user_id: 1>}, missing required keys: [:id]): 21 21: %h3 22 22: -# いいね件数: #{@tweet.likes.count} 23 23: - if current_user.already_liked?(tweet) 24 24: = button_to 'いいねを取り消す', tweet_like_path(tweet), method: :delete 25 25: - else 26 26: = button_to 'いいね', tweet_likes_path(tweet) 27 27: %h2 いいねしたユーザー 28 29app/views/tweets/_tweet.html.haml:24 30app/views/tweets/index.html.haml:4 31app/views/tweets/index.html.haml:3

##ビューファイル

tweet.html.haml

haml

1%main.Index 2 %section.TweetField 3 - @tweets.each do |tweet| 4 %article.PostedItem 5 .ArticleHeader 6 %ul.More 7 %li 8 = icon('fas', 'bars') 9 %ul 10 %li 11 = link_to '詳細', tweet_path(tweet.id), method: :get 12 - if user_signed_in? && current_user.id == tweet.user_id 13 %li 14 = link_to '編集', edit_tweet_path(tweet.id), method: :get 15 %li 16 = link_to '削除', tweet_path(tweet.id), method: :delete 17 18 .Picture 19 .content_post{style: "background-image: url(#{tweet.image})"} 20 .ReactionBtn 21 = icon('fas', 'star', class: 'ReactionBtn__good') 22 - tweet.tags.each do |tag| 23 = tag.tag_name 24 %h3 25 - if current_user.already_liked?(tweet) 26 = button_to 'いいねを取り消す', tweet_like_path(tweet),method: :delete 27 - else 28 = button_to 'いいね', tweet_likes_path(tweet) 29 %h2 いいねしたユーザー 30 - tweet.liked_users.each do |user| 31 %li= user.email 32 = link_to "ホームへ戻る", tweets_path 33 34

##コントローラー

tweets_controller.rb

ruby

1class TweetsController < ApplicationController 2 before_action :set_tweet, only: [:edit, :show] 3 before_action :move_to_index, except: [:index, :show, :search] 4 before_action :authenticate_user!, only: [:show, :create] 5 6 def index 7 @tweets = Tweet.includes(:user).order("created_at DESC") 8 end 9 10 def new 11 @tweet = Tweet.new 12 end 13 14 def create 15 @tweet = Tweet.create(tweet_params) 16 @tweet.user_id = current_user.id 17 18 end 19 20 def destroy 21 tweet = Tweet.find(params[:id]) 22 tweet.destroy 23 end 24 25 def edit 26 end 27 28 def update 29 tweet = Tweet.find(params[:id]) 30 tweet.update(tweet_params) 31 end 32 33 def show 34 @like = Like.new 35 @comment = Comment.new 36 @comments = @tweet.comments.includes(:user) 37 end 38 39 def search 40 @tweets = Tweet.search(params[:keyword]) 41 end 42 43 private 44 def tweet_params 45 params.require(:tweet).permit(:image, :text).merge(user_id: current_user.id) 46 end 47 48 def set_tweet 49 @tweet = Tweet.find(params[:id]) 50 end 51 52 def move_to_index 53 unless user_signed_in? 54 redirect_to action: :index 55 end 56 end 57 58 def tag_params 59 params.require(:tweet).permit(:tag_names) 60 end 61end
likes_controller.rb

ruby

1class LikesController < ApplicationController 2 def create 3 @like = current_user.likes.create(tweet_id: params[:tweet_id]) 4 redirect_back(fallback_location: root_path) 5 end 6 7 def destroy 8 @like = Like.find_by(tweet_id: params[:tweet_id], user_id: current_user.id) 9 @like.destroy 10 redirect_back(fallback_location: root_path) 11 end 12end 13

モデル

tweet.rb

ruby

1class Tweet < ApplicationRecord 2 validates :text, presence: true 3 belongs_to :user 4 has_many :comments 5 has_many :tweet_tag_relations, dependent: :destroy 6 has_many :tags, through: :tweet_tag_relations 7 has_many :likes 8 has_many :liked_users, through: :likes, source: :user 9 10def liked_by?(user) 11 likes.where(user_id: user.id).exists? 12end 13 def save_tags(tag_list) 14 tag_list.each do |tag| 15 unless find_tag = Tag.find_by(tag_name: tag.downcase) 16 begin 17 self.tags.create!(tag_name: tag) 18 rescue 19 nil 20 end 21 else 22 TweetTagRelation.create!(tweet_id: self.id, tag_id: find_tag.id) 23 end 24 end 25 end 26 def self.search(search) 27 if search 28 Tweet.where('text LIKE(?)', "%#{search}%") 29 else 30 Tweet.all 31 end 32 end 33end
tag.rb

ruby

1class Tag < ApplicationRecord 2 before_save :downcace_tag_name 3 4 has_many :tweet_tag_relations, dependent: :destroy 5 has_many :tweets, through: :tweet_tag_relations 6 7 validates :tag_name, presence: true, uniqueness: true, length: { maximum: 50 } 8 9 private 10 def downcase_tag_name 11 self.tag_name.downcase! 12 end 13end 14
tweet_tag_relation.rb(中間テーブル)

ruby

1class TweetTagRelation < ApplicationRecord 2 belongs_to :Tweet 3 belongs_to :tag 4end

##ルーティング

routes.rb

ruby

1Rails.application.routes.draw do 2 devise_for :users 3 root to: 'tweets#index' 4 5 resources :users, only: :show 6 resources :tweets do 7 resources :likes, only: [:create, :destroy] 8 resources :comments, only: :create 9 collection do 10 get 'search' 11 end 12 end 13end

マイグレーションファイル

2020XXX_create_like.rb
class CreateLikes < ActiveRecord::Migration[6.0] def change create_table :likes do |t| t.references :user, null: false, foreign_key: true t.references :tweet, null: false, foreign_key: true t.timestamps end end end

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KotaTakahashi

2020/07/30 23:38

routes.rbを追加しました。お願いします。
guest

回答1

0

削除するのは Tweetではなく likeですから、likeも渡さすひつようがあります。tweet_like_path(tweet) ⇒ tweet_like_path(tweet,like)
そのlikeをview上で得るが嫌で、今のcotrollerの様にdestroyで特定するのでしたら、tweet.idだけを受け取る routesを新たに定義が必要です。

投稿2020/07/31 00:45

winterboum

総合スコア23567

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KotaTakahashi

2020/07/31 02:07

ご回答ありがとうございます。 tweet_like_path(tweet,like)に変更したところ、 Name Error undefined local variable or method `like' と出てしまいました。コントローラーか何かのスペルミスかなとも思ったのですが、わかりませんでした。 どこかしらコントローラーにlikeの受け渡しが不足しているということでしょうか? https://gyazo.com/44052183ab6d587d65b6c6a08ef4338c
winterboum

2020/07/31 04:05

どの like はどのlikeなのか? を事前に代入しておく必要があります。 どの like なの?
KotaTakahashi

2020/07/31 04:45

理解度が低くて申し訳ないです。 tweet_like_pathで指定されているのは、likes#destroyなので、likesコントローラーの@like = current_user.likes.create(tweet_id: params[:tweet_id])のlikeという認識で間違い無いでしょうか。
winterboum

2020/07/31 07:44

@like = Like.find_by(tweet_id: params[:tweet_id], user_id: current_user.id) こっちでないの?
KotaTakahashi

2020/07/31 07:54

すみません間違えました。そちらだと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問