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

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

ただいまの
回答率

88.21%

Rails非同期「いいね」機能 create時のみレンダリングしない

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 248

kkbeams

score 17

rails でコンテンツを投稿し、各コンテンツの詳細画面に非同期で「いいね機能」を作っています。

------------起きている問題------------

コンテンツ詳細画面を開く 

ボタン状態:未いいね

↓ いいね押す(createされるがレンダリングしない) ※ここが問題点

ボタン状態:未いいね

↓ リロードしてみる

ボタン状態:いいね済

↓いいね押す(destroyされ、レンダリングされる)

ボタン状態:未いいね

---------繰り返し---------

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

ActionView::Template::Error (No route matches {:action=>"destroy", :content_id=>5, :controller=>"user/favorites"}, missing required keys: [:id]):
    1: <% if content.liked_by?(current_user) %>
    2:   <%= button_to content_favorite_path(content.id), method: :delete, remote: true, class:"buy-btn fav-delete-btn" do %>
    3:     <span>いいね解除</span>
    4:   <% end %>
    5: <% else %>

app/views/user/favorites/_favorite.html.erb:2
app/views/user/favorites/create.js.erb:1

routes.rb

authenticated :user do
    scope module: :user do
      resources :contents, only: [:index, :new, :create, :show, :destroy] do
        resources :favorites, only: [:create, :destroy]
      end
    end
end

model

content.rb

class Content < ApplicationRecord
  belongs_to :user
  has_many :favorites, dependent: :destroy

  validates :user_id, presence: true

  def liked_by?(user)
    favorites.where(user_id: user.id).exists?
  end
end


user.rb

class User < ApplicationRecord
  has_many  :contents, dependent: :destroy
  has_many  :favorites, dependent: :destroy
end


favorite.rb

class Favorite < ApplicationRecord
  belongs_to :user
  belongs_to :content
  validates  :user_id, uniqueness: { scope: :content_id }
end

favorites_controller.rb

(app/controllers/user/favorites_controller.rb)

class User::FavoritesController < ApplicationController
  before_action :set_variables

  def create
    @favorite = current_user.favorites.create(content: @content)
  end

  def destroy
    favorite = Favorite.find_by(content: @content, user_id: current_user.id)
    favorite.destroy
  end

  private

    def set_variables
      @content = Content.find(params[:content_id])
      @id_name = "#favorites_buttons_#{@content.id}"
    end
end

show.html.erb

(app/views/user/contents/show.html.erb)

<div id="favorites_buttons_<%= @content.id %>">
  <%= render partial: 'user/favorites/favorite', locals: { content: @content} %>
</div>

_favorite.html.erb

(app/views/user/favorites/_favorite.html.erb)

<% if content.liked_by?(current_user) %>
  <%= button_to content_favorite_path(content.id), method: :delete, remote: true, class:"buy-btn fav-delete-btn" do %>
    <span>いいね解除</span>
  <% end %>
<% else %>
  <%= button_to content_favorites_path(content.id), method: :post, remote: true, class:"buy-btn fav-btn" do %>
    <span>いいね!</span>
  <% end %>
<% end %>

create.js.erb destroy.js.erb

(app/views/user/favorites/create.js.erb)
(app/views/user/favorites/destroy.js.erb)

$('<%= @id_name %>').html("<%= j(render partial: 'user/favorites/favorite', locals: {content: @content}) %>");

試したこと

ルーティングがネスト構造になっているため、viewファイルの位置がおかしいのかと思い、フォルダー作ったり、ファイルを移動させたりしたのですが、解決できませんでした。。。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • no1knows

    2020/08/30 17:43

    問題点のところで、発生している問題・エラーメッセージが表示されるという認識で良いのでしょうか?

    キャンセル

回答 1

checkベストアンサー

0

以下のエラー文を見ると missing required keys: [:id]とかかれているのことから、必要なIDがないために、レンダリングに失敗していそうです。

ActionView::Template::Error (No route matches {:action=>"destroy", :content_id=>5, :controller=>"user/favorites"}, missing required keys: [:id]):

いいね解除ボタンで、content_favorite_path(content.id)とかかれていますが、deleteのPathで引数が2つ必要なところを1つしか渡していないのかと思いました。以下のようにするといかがでしょうか(引数の値はとりあえず適当です)。 

content_favorite_path(content.id, content.id)
  • 1つめの引数が、およそDeleteしたいFavoriteテーブルのID
  • 2つめの引数が、content_id

になる気がします。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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