こんにちは。RUNTEQ75期生のリリコです。
2回目の投稿です。
今回は最近カリキュラムで実装した
掲示板アプリのブックマーク一覧を表示する機能について書いていきます。
目次
- 最初に書いたコード
- 何がダメだったのか
- has_many :through の意味
- おわりに
最初に書いたコード
- app/controllers/boards_controller.rb
def bookmarks
@bookmark = current_user.bookmarks.find(params[:id])
end
ブックマークの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に伝えています。
おわりに
過去のカリキュラムを参考にコードを書いていましたが、
- テーブル間の関係
- 何をしたいのか
これらを明確に理解していなかったことで
エラーメッセージから原因が特定できませんでした。
今後は、実装前にテーブル間の関係と「何を取得したいのか」を
整理することを意識したいと思います。
参考
