0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ブックマーク一覧が表示できない原因と中間テーブルの理解(has_many :through)

0
Posted at

こんにちは。RUNTEQ75期生のリリコです。
2回目の投稿です。

今回は最近カリキュラムで実装した
掲示板アプリのブックマーク一覧を表示する機能について書いていきます。

目次

  1. 最初に書いたコード
  2. 何がダメだったのか
  3. has_many :through の意味
  4. おわりに

最初に書いたコード

  • app/controllers/boards_controller.rb
def bookmarks
  @bookmark = current_user.bookmarks.find(params[:id])
end
  • 結果:エラー画面
    image.png

ブックマークのIDが見つからない・・・?

調べても解決方法がわからなかったのでAIに相談したところ、
一覧ページのURLには特定のIDが含まれていないにもかかわらず、
find(params[:id]) で「特定の1件」を探そうとしていました。
そのため、該当するIDが見つからずエラーになっていました。

何がダメだったのか

正しいコード

  • boards_controller.rb
def bookmarks
  @bookmark_boards = current_user.bookmark_boards.all #allは省略可
end
  • user.rb
has_many :bookmark_boards, through: :bookmarks, source: :board

まず、やりたかったことは、
「ログインしているユーザーがブックマーク一覧をクリックしたら、ブックマークした掲示板の一覧を表示できるようにすること」です。

findで1件しか取得していない

find(params[:id])

findは「特定の1件だけ取ってくる」メソッドです。
見つからない場合はエラー(ActiveRecord::RecordNotFound)になります。

取得しているのがBookmark

current_user.bookmarks

表示したいのは掲示板一覧なので、Bookmarkモデルそのものではなく、
その先にある、掲示板のタイトルや内容を持っているBoardモデルを取得する必要があります。

テーブルの関係を図で表すと、以下のようになります。

User
 ↓
Bookmark  #「誰がどの掲示板をブックマークしたか」を保存するための橋渡しテーブル
 ↓
Board  # 表示したい掲示板のタイトルや内容

すなわち、BookmarkはUserとBoardをつなぐ中間テーブルなのです。

has_many :through の意味

  • user.rb
has_many :bookmark_boards, through: :bookmarks, source: :board

これは、「bookmark_boardsという名前でBoardを呼び出せるようにする宣言」をしています。

つまり、boards_controller.rbで「current_user.bookmark_boards と書いたら
ブックマークしている掲示板を取れるようにしてね」とRailsに伝えています。

おわりに

過去のカリキュラムを参考にコードを書いていましたが、

  • テーブル間の関係
  • 何をしたいのか

これらを明確に理解していなかったことで
エラーメッセージから原因が特定できませんでした。
今後は、実装前にテーブル間の関係と「何を取得したいのか」を
整理することを意識したいと思います。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?