先日ポートフォリオを作成していた際に、少し悩んだことを復習がてら書いていきたいと思います。
【環境】
- Rails 6.1.5.1
- ruby 2.6.3
【前提】
- 投稿機能を実装済み(この記事では、Postモデル)
- いいね機能を実装済み(この記事では、Favoriteモデル)
【リレーション】
- UserとPost(1対多)
- UserとFavorite(1対多)
- PostとFavorite(1対多)
【実現したいこと】
タイトル通り(少し分かりにくい日本語かも)ですが、ある1人のuserの全投稿に紐づく全てのいいね数を表示させたいと思います。
userの詳細ページを作成している際に、この全いいね数を表示させたいなと思ったのがきっかけです。
【方法】
①userの全投稿数を取得(関係ないですが、復習のため)
これは簡単ですね!countメソッドを使って数えます。
user.posts.count
②次に、1つのpostに紐づくいいね数
post.favorites.count
③では、本題の取得方法です!
色々試した結果、下記のコードで全いいね数の取得ができました。
user.posts.inject(0) { |sum, post| sum + post.favorites.count }
④「inject」とは
injectは繰り返しの計算ができるメソッドです。使用例を見てみましょう!
(1..6).inject(0) { |sum,num| p sum+=num }
実行結果
1
3
6
10
15
21
1~6までの数字をどんどん足していっていることが分かります。injectの右にある「0」は、「sum」に代入される初期値です。なので、他の数字にすると実行結果も変わっていくると思います。「num」は(1..6)の一つ一つの要素になります。
ちなみにeach文でも書くことができますが、スッキリしたコードにしたいと思った結果injectに辿り着きました。
#eachバージョン(同じ結果になるはずです!)
array = 1..6
sum = 0
array.each do |num|
sum += num
p sum
end
⑤最後にもう一度③のコードを見てみましょう!
user.posts.inject(0) { |sum, post| sum + post.favorites.count }
1.user.posts → userの全ての投稿を用意する。
2.(0) → sumの初期値を0にする。
3.|sum, post| → sumは足した合計を入れていく為のもの。postはuser.postsの中の一つ一つのpost。
4.sum + post.favorites.count → 一つ一つのpostのいいね数を取得し、sumに足していく。
5.完成!!
終わりに
railsの勉強だけでなく、rubyのコードを書けるようにすることも大事だなあと感じました。
最後までご覧いただきありがとうございました!!