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

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

ただいまの
回答率

88.64%

お気に入り機能の動作がうまくいかない

解決済

回答 1

投稿 編集

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

anguraaaa

score 21

前提・実現したいこと

railsで掲示板のお気に入り機能(ajax)を実装しています。

押したお気に入りボタンと掲示板が対応していないです。再読込すると、正しく動作します。
ですから、ajaxのコードに問題があると思います。

画像を撮影しました。

タイトル0ではうまく動作します
https://gyazo.com/6c59352a587feed7f96bd204e2b38ce4

タイトル1の場合はうまくいきません
https://gyazo.com/76da50efc5ebc1b0f179028f18110989

掲示板=board, お気に入り=bookmarkとしています

ご教授のほどよろしくお願いいたします。

該当のソースコード

boards_controller.rb

class BoardsController < ApplicationController
  before_action :set_board, only: %i[edit update destroy]
  def index
    @boards = Board.all.includes(:user)
  end

  def new
    @board = Board.new
  end

  def create
    @board = current_user.boards.new(board_params)

    if @board.save
      redirect_to boards_url, success: '掲示板を作成しました'
    else
      flash.now[:danger] = '掲示板を作成できませんでした'
      render :new
    end
  end

  def edit; end

  def update
    if @board.update(board_params)
      redirect_to board_url(@board), success: '掲示板を更新しました'
    else
      flash.now[:danger] = '掲示板を更新できませんでした'
      render :edit
    end
  end

  def show
    @board = Board.find(params[:id])
    @comment = Comment.new
    @comments = @board.comments.includes(:user).order(created_at: :desc)
  end

  def destroy
    @board.destroy!
    redirect_to boards_url, warning: '掲示板を削除しました'
  end

  def bookmarks
    @bookmark_boards = current_user.bookmark_boards.includes(:user)
  end

  private

  def board_params
    params.require(:board).permit(:title, :body, :image, :image_cache)
  end

  def set_board
    @board = current_user.boards.find(params[:id])
  end
end
bookmarks_controller.rb

class BookmarksController < ApplicationController
  before_action :set_board, only: %i[create destroy]
  def create
    @bookmark = current_user.bookmarks.new(board_id: params[:board_id])
    @bookmark.save
  end

  def destroy
    @bookmark = current_user.bookmarks.find_by(board_id: params[:board_id])
    @bookmark.destroy!
  end

  private

  def set_board
    @board = Board.find(params[:board_id])
  end
end
user.rb

class User < ApplicationRecord
  authenticates_with_sorcery!

  has_many :boards, dependent: :destroy
  has_many :comments, dependent: :destroy
  has_many :bookmarks, dependent: :destroy
  has_many :bookmark_boards, through: :bookmarks, source: :board

  validates :last_name, presence: true, length: { maximum: 255 }
  validates :first_name, presence: true, length: { maximum: 255 }
  validates :password, length: { minimum: 3 }, if: -> { new_record? || changes[:crypted_password] }
  validates :password, confirmation: true, if: -> { new_record? || changes[:crypted_password] }
  validates :password_confirmation, presence: true, if: -> { new_record? || changes[:crypted_password] }

  validates :email, presence: true, uniqueness: true

  def own?(object)
    id == object.user_id
  end
end
board.rb

class Board < ApplicationRecord
  mount_uploader :image, ImagesUploader

  belongs_to :user
  has_many :comments, dependent: :destroy
  has_many :bookmarks, dependent: :destroy

  validates :title, presence: true, length: { maximum: 255 }
  validates :body, presence: true, length: { maximum: 65_535 }

  def bookmark_by?(user)
    bookmarks.where(user_id: user.id).exists?
  end
end
bookmark.rb

class Bookmark < ApplicationRecord
  belongs_to :user
  belongs_to :board

  validates :user_id, uniqueness: { scope: :board_id }
end
こちらはboards/index.html.erbの部分テンプレートです

boards/_board.html.erb

<div class="col-sm-12 col-lg-4 mb-3">
  <div id="board-id-1">             
    <div class="card">
      <%= image_tag board.image.url, size: '300x200' %>
        <div class="card-body">
          <h4 class="card-title">
            <%= link_to board.title, board_path(board) %>
          </h4>
          <% if current_user.own?(board) %>
            <%= render 'crud_menus', board: board %>
          <% else %>
            <div id = "bookmark_btn_<% board.id %>" style='display: inline; float: right;'>
              <%= render 'bookmark_area', board: board %>
            </div>
          <% end %>
          <ul class="d-flex flex-column list-unstyled">
            <li class="p-0"><i class="fas fa-user"></i>  <%= board.user.decorate.full_name %></li>
            <li class="p-0"><i class="far fa-calendar-alt"></i>  <%= l board.created_at %></li>
          </ul>
          <p class="card-text"><%= board.body %></p>
        </div>
    </div>
  </div>
</div>
こちらは_board.html.erbの部分テンプレートです

boards/_bookmark_area.html.erb

<% if board.bookmark_by?(current_user) %>
  <%= render 'bookmarks/unbookmark', board: board %>
<% else %>
  <%= render 'bookmarks/bookmark', board: board %>
<% end %>
bookmarks/_bookmark.html.erb

<%= link_to icon('far', 'star'), board_bookmarks_path(board.id), remote: true, method: :post, id: :"js-bookmark-button-for-board-#{board.id}" %>
bookmarks/unbookmark.html.erb

<%= link_to icon('fas', 'star'), board_bookmarks_path(board.id), remote: true, method: :delete, id: :"js-bookmark-button-for-board-#{board.id}" %>
bookmarks/create.js.erb

$('#bookmark_btn_<% @board.id %>').html("<%= j(render 'boards/bookmark_area', { board: @board })%>");
bookmarks/destroy.js.erb

$('#bookmark_btn_<% @board.id %>').html("<%= j(render 'boards/bookmark_area', { board: @board })%>");
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

check解決した方法

0

create.js.erbとdestroy.js.erbファイルのidの部分を
'#bookmark_btn_<% @board.id %>'から'#js-bookmark-button-for-board-<%= @board.id %>'へと変更することで解決しました。
つまり、_board.html.erbにidを与えるのではなく、_bookmark.html.erbと_unbookmark.html.erbのidを直接、受け取ってboards/bookmark_area.html.erbにレンダリングすることでajaxの処理がうまくいきました。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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