ActionController::UrlGenerationError(いいねボタンのmethod:delete)
- 評価
- クリップ 0
- VIEW 359
解決したいこと
- いいね機能を実装中です。その際、いいねボタンを押すと、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
関連のする箇所
エラー画面
実行時のターミナル
Started GET "/tweets" for ::1 at 2020-07-30 23:55:11 +0900
Processing by TweetsController#index as HTML
Rendering tweets/index.html.haml within layouts/application
Tweet Load (1.0ms) SELECT "tweets".* FROM "tweets" ORDER BY created_at DESC
↳ app/views/tweets/index.html.haml:3
User Load (0.6ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 [["id", 1]]
↳ app/views/tweets/index.html.haml:3
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
↳ app/views/tweets/_tweet.html.haml:9
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]]
↳ app/views/tweets/_tweet.html.haml:19
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]]
↳ app/models/user.rb:11:in `already_liked?'
Rendered tweets/_tweet.html.haml (Duration: 19.4ms | Allocations: 4272)
Rendered tweets/index.html.haml within layouts/application (Duration: 35.9ms | Allocations: 6190)
Completed 500 Internal Server Error in 47ms (ActiveRecord: 3.3ms | Allocations: 6799)
ActionView::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: %h3
22: -# いいね件数: #{@tweet.likes.count}
23: - if current_user.already_liked?(tweet)
24: = button_to 'いいねを取り消す', tweet_like_path(tweet), method: :delete
25: - else
26: = button_to 'いいね', tweet_likes_path(tweet)
27: %h2 いいねしたユーザー
app/views/tweets/_tweet.html.haml:24
app/views/tweets/index.html.haml:4
app/views/tweets/index.html.haml:3
ビューファイル
tweet.html.haml
%main.Index
%section.TweetField
- @tweets.each do |tweet|
%article.PostedItem
.ArticleHeader
%ul.More
%li
= icon('fas', 'bars')
%ul
%li
= link_to '詳細', tweet_path(tweet.id), method: :get
- if user_signed_in? && current_user.id == tweet.user_id
%li
= link_to '編集', edit_tweet_path(tweet.id), method: :get
%li
= link_to '削除', tweet_path(tweet.id), method: :delete
.Picture
.content_post{style: "background-image: url(#{tweet.image})"}
.ReactionBtn
= icon('fas', 'star', class: 'ReactionBtn__good')
- tweet.tags.each do |tag|
= tag.tag_name
%h3
- if current_user.already_liked?(tweet)
= button_to 'いいねを取り消す', tweet_like_path(tweet),method: :delete
- else
= button_to 'いいね', tweet_likes_path(tweet)
%h2 いいねしたユーザー
- tweet.liked_users.each do |user|
%li= user.email
= link_to "ホームへ戻る", tweets_path
コントローラー
tweets_controller.rb
class TweetsController < ApplicationController
before_action :set_tweet, only: [:edit, :show]
before_action :move_to_index, except: [:index, :show, :search]
before_action :authenticate_user!, only: [:show, :create]
def index
@tweets = Tweet.includes(:user).order("created_at DESC")
end
def new
@tweet = Tweet.new
end
def create
@tweet = Tweet.create(tweet_params)
@tweet.user_id = current_user.id
end
def destroy
tweet = Tweet.find(params[:id])
tweet.destroy
end
def edit
end
def update
tweet = Tweet.find(params[:id])
tweet.update(tweet_params)
end
def show
@like = Like.new
@comment = Comment.new
@comments = @tweet.comments.includes(:user)
end
def search
@tweets = Tweet.search(params[:keyword])
end
private
def tweet_params
params.require(:tweet).permit(:image, :text).merge(user_id: current_user.id)
end
def set_tweet
@tweet = Tweet.find(params[:id])
end
def move_to_index
unless user_signed_in?
redirect_to action: :index
end
end
def tag_params
params.require(:tweet).permit(:tag_names)
end
end
likes_controller.rb
class LikesController < ApplicationController
def create
@like = current_user.likes.create(tweet_id: params[:tweet_id])
redirect_back(fallback_location: root_path)
end
def destroy
@like = Like.find_by(tweet_id: params[:tweet_id], user_id: current_user.id)
@like.destroy
redirect_back(fallback_location: root_path)
end
end
モデル
tweet.rb
class Tweet < ApplicationRecord
validates :text, presence: true
belongs_to :user
has_many :comments
has_many :tweet_tag_relations, dependent: :destroy
has_many :tags, through: :tweet_tag_relations
has_many :likes
has_many :liked_users, through: :likes, source: :user
def liked_by?(user)
likes.where(user_id: user.id).exists?
end
def save_tags(tag_list)
tag_list.each do |tag|
unless find_tag = Tag.find_by(tag_name: tag.downcase)
begin
self.tags.create!(tag_name: tag)
rescue
nil
end
else
TweetTagRelation.create!(tweet_id: self.id, tag_id: find_tag.id)
end
end
end
def self.search(search)
if search
Tweet.where('text LIKE(?)', "%#{search}%")
else
Tweet.all
end
end
end
tag.rb
class Tag < ApplicationRecord
before_save :downcace_tag_name
has_many :tweet_tag_relations, dependent: :destroy
has_many :tweets, through: :tweet_tag_relations
validates :tag_name, presence: true, uniqueness: true, length: { maximum: 50 }
private
def downcase_tag_name
self.tag_name.downcase!
end
end
tweet_tag_relation.rb(中間テーブル)
class TweetTagRelation < ApplicationRecord
belongs_to :Tweet
belongs_to :tag
end
ルーティング
routes.rb
Rails.application.routes.draw do
devise_for :users
root to: 'tweets#index'
resources :users, only: :show
resources :tweets do
resources :likes, only: [:create, :destroy]
resources :comments, only: :create
collection do
get 'search'
end
end
end
マイグレーションファイル
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
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
0
削除するのは Tweetではなく likeですから、likeも渡さすひつようがあります。tweet_like_path(tweet) ⇒ tweet_like_path(tweet,like)
そのlikeをview上で得るが嫌で、今のcotrollerの様にdestroyで特定するのでしたら、tweet.idだけを受け取る routesを新たに定義が必要です。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.31%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
winterboum
2020/07/31 05:31
routes.rb を
KotaTakahashi
2020/07/31 08:38
routes.rbを追加しました。お願いします。