sugulogの日記

Rails、 N + 1問題!マイページを実装しよう!!〜後編〜

スポンサードリンク

f:id:sugulog:20201027175500p:plain

こんにちは、すぐるです!

sugulogをお読みいただきありがとうございます!!

このブログは、「 過去の無知な自分に向けてわかりやすく説明するなら?? 」を基準に書いています。

少しでもお役に立てれば幸いです。

 

今回は、前回の続きということで

  • マイページの実装

について簡単に解説します!!

その為このブログを読むことで、N + 1問題について理解できるのはもちろん、マイページ機能の実装についての理解も深まります。

是非最後までご愛読ください。

 

今回は、

  •  マイページの実装

  • N + 1問題

の順で解説していきます。

また、前回のブログの内容を引き継いで記述しています。

そのため、前回のブログを必ず1度読んでからお読みください。

sugulog.hatenadiary.jp

では早速、みていきましょう!!

・マイページの実装

マイページはユーザーに関するページなので、usersコントローラーに記述していきます。

では始めにルーティングですが、以下のように記述しました。

f:id:sugulog:20201029131409p:plain

5行目に注目してください。

詳細ページはshowアクションを定義します。

次に今回はヘッダーにマイページに遷移するためのボタンを、以下のように記述しました。

f:id:sugulog:20201029135439p:plain

19行目に注目してください。

引数にcurrent_user.idを与えることで現在ログインしているユーザーのidを取得し、そのユーザーのマイページに遷移することができます。

またcurrent_user.nicknameと記述することで、usersテーブルのnicknameカラムから現在ログイン中のユーザーのnicknameを取得できます。

では次にコントローラーを定義していきます。

まずはコントローラーを作成するために、rails g controller usersを実行しました。

そして、以下のように記述しました。

f:id:sugulog:20201029151718p:plain

showアクションを定義しています。

3行目はマイページに遷移する際に送られてきたidをparamsとして受け取り、findでUserモデルから該当するユーザーを取得しuserに代入しています。

4行目ではそのuserのnicknameを取得し、5行目ではtweetsを取得しそれぞれインスタンス変数に代入しています。

userのidでツイートが取得できるのはTweetモデルにuser_idカラムを追加し、UserモデルとTweetモデルが1対多のアソシエーションを結んでいるからです。

では次にマイページのビューを、以下のように記述しました。

f:id:sugulog:20201029142953p:plain

基本的に一覧ページと同じ構造ですが、@tweetsの中身はマイページに遷移する際に送られてきたidのユーザーのツイートで、投稿されている全てのツイートとは異なるのを押さえておきましょう!

またツイートに表示されているnameから、投稿したユーザーのマイページに遷移できるようにもしましょう!!

f:id:sugulog:20201029153812p:plain

8〜10行目に注目してください。

aタグのhref属性として、showアクションへのパスを指定しています。

その際のidですがtweetからuserのidを取得したいため、eachで取得した1つ1つのツイートを使いtweet.user.idとすることで取得することができます。

tweetからuserのidを取得できるのはTweetモデルにuser_idカラムを追加し、tweetに対しユーザーは1人という1対1の関係をアソシエーションによって定義しているためです。

後はtweet詳細ページに表示されるnameからも遷移できるよう記述しました。

f:id:sugulog:20201029155359p:plain

7〜9行目に注目してください。

showアクションで既に@tweetにツイートidを代入しているので、上記のような記述になります!

実際に遷移されるか動きだけ確認しておきましょう!!

・N + 1問題

アソシエーションを利用した際にデータベースへのアクセス回数が多くなり、アプリケーションのパフォーマンス低下に繋がる問題のこと。

通常は単に1つのモデルから情報を取得しますが、アソシエーションを定義し複数のモデルから情報を取得しようとすると、その分だけデータベースにアクセスする回数も増えていきます。

特にallメソッドなど全てのデータを複数のモデルから取得する際は、その影響を受けやすいです。

その結果、データを取得するまでにかなりの時間を使ったりなど、アプリケーションのパフォーマンスが落ちます。

それでは使い勝手が悪く、実用的とは言えません。

そこでincludesメソッドを使用し、その問題を解決していきます!

・includesメソッド

引数に指定された関連モデルを1度のアクセスでまとめて取得するメソッド。

記述の仕方としては、モデル名.includes(:紐づくモデル名)です。

そのため今回は、以下のように記述しました。

f:id:sugulog:20201029163512p:plain

7行目に注目してください。

今回は紐づくモデルとしてuserを指定しています。

またincludesメソッドは該当する全てのレコードを取得するため、allの記述を省略することもできます。

この記述のおかげでツイートを表示するたびにuserにアクセスするのではなく、一気に両方のレコードを取得しアクセス回数を減らしています。

 

以上、今回のブログでした。

N + 1問題について理解でき、マイページ機能の実装についての理解も深まりましたか??

アソシエーションを利用した記述が多いため、1つずつしっかりと理解を深めていきましょう(≧∀≦)/

 

 

最後に!!

今後も、「 過去の無知な自分に向けてわかりやすく説明するなら?? 」を基準にブログを書いていきます。

少しでも気になった方はお試しでもいいので1度、読者登録お願いします!

またTwitterでもプログラミングに関することを中心に情報を発信してます。

宜しければそちらのフォローもお願いします。

最後までご愛読いただきありがとうございました!!