ここではアソシエーションについて学習する。
Railsを使う上でとても便利で大事な機能であるため、理解できるまで繰り返し学習が必要である。
アソシエーションを利用する
Railsにはモデル間の関係を管理するアソシエーションという機能がある。
今回の作業ではこのアソシエーションという機能を実装する。
アソシエーション
アソシエーションとはモデル間の関連付けを管理する機能のことで、定義しておくことでモデルをまたいだデータの呼び出しをより簡単に行うことができるようになる。
今回の場合、UserモデルとTweetモデルをアソシエーションで関連付けする。
下のヒントを参考にしながら実装を行う。
作業内容
1.アソシエーションを定義する
2.アソシエーションを実装する
1.アソシエーションを定義する
アソシエーションを利用するために、まずはモデル間の関係を定義する。
アソシエーションを利用するには以下の2つの条件を満たす必要がある。
- モデルクラスにhas_manyやbelongs_toなどの定義がされている
- 所属する側のテーブルに所属するクラス名_idというカラムがある
②の実装に関してはすで行っているため、これから①の実装に関しての説明を行う。
現在PicTweetにはサインアップという機能があり、利用者がユーザーを作成してログインを行うことができる。
また、ツイートの投稿に関してはログインしたユーザーのみが行うことができる。
つまり、全てのツイートはいずれかのユーザーが作成したものであり、逆に言えばユーザーは自分の作成したツイートを複数個所持している状態といえる。
Userモデルの視点で考えると、あるuserの作成したtweetが複数個ある状態と言える。
この状態のことをhas manyの関係といい、今回の場合には「User has many Tweets」の状態であると言える。
この関係をアソシエーションで定義するためにはUserモデルのモデルファイルを編集する。
「User has many Tweets」の状態を定義するため、Userモデルのモデルファイルにhas_many :tweetsと追記する。
以下の指示に従い、app/models/user.rbを編集する
app/models/tweet.rb
class Tweet < ApplicationRecord belongs_to :user end
また、Tweetモデルの視点で考えると、全てのtweetはいずれかのuserに属している状態と言える。
この状態のことをbelongs toの関係といい、今回の場合は「Tweet belongs to User」の状態であると言える。
この関係をアソシエーションで定義するためにはTweetモデルのモデルファイルを編集する。
「Tweet belongs to User」の関係を定義するため、Tweetモデルのモデルファイルにbelongs_to :userと追記する。
2.アソシエーションを実装する
この関係をアソシエーションで定義するためにはTweetモデルのモデルファイルを編集する。
「Tweet belongs to User」の関係を定義するため、Tweetモデルのモデルファイルにbelongs_to :userと追記する。
class Tweet < ApplicationRecord belongs_to :user end
以下の指示に従い、app/models/tweet.rbを編集する
app/models/tweet.rb
class Tweet < ApplicationRecord belongs_to :user end
2.アソシエーションを実装する
以上の作業でアソシエーションを定義することができた。
そこで、実際にアソシエーションを利用して実装を行っていく。
さきほど編集を行ったusers_controller.rbのshowアクション部分でのデータの呼び出しにアソシエーションを使用して記述を行う。
アソシエーションを定義すると、モデルをまたいだデータの呼び出しをより直感的に行うことができる。
便利さを実感するため、アソシエーションを使用しない場合とする場合のコードの違いを見てみまる。
アソシエーションを使用しない場合は、以下のように現在ログイン中のユーザーが投稿したツイートを取得する。
例としてコンソールからのデータの呼び出しを行う。
【例】アソシエーションを使用しない
ターミナル
$ rails c [1] pry(main)> user = User.find(1) [2] pry(main)> Tweet.where(user_id: user.id) => [#<Tweet id: 1, image: "http://photo1.jpg", text: "いい景色だ。", created_at: "2014-12-06 09:00:00", updated_at: "2014-12-06 09:00:00", user_id: 1>, #<Tweet id: 1, image: "http://photo2.jpg", text: "楽しい思い出は消えない。", created_at: "2014-12-06 10:00:00", updated_at: "2014-12-06 10:00:00", user_id: 1>]
tweetsテーブルに対して、user_idがuserのidと等しいレコードを取得している。
対して、これと同じことをアソシエーションを利用すると以下のように記述できる。
【例】アソシエーションを使用する
$ rails c
[1] pry(main)> user = User.find(1)
[2] pry(main)> user.tweets
=> [#<Tweet id: 1, image: "http://photo1.jpg", text: "いい景色だ。", created_at: "2014-12-06 09:00:00", updated_at: "2014-12-06 09:00:00", user_id: 1>,
#<Tweet id: 1, image: "http://photo2.jpg", text: "楽しい思い出は消えない。", created_at: "2014-12-06 10:00:00", updated_at: "2014-12-06 10:00:00", user_id: 1>]
Userモデルに「User has many Tweets」の状態のアソシエーションを定義したため、
Userモデルのインスタンス.tweetsと記述するだけでそのインスタンスが所持している
ツイートを取得することができる。
早速、users_controllerのshowアクション内を編集してアソシエーションを利用してみる。
問題1:アソシエーションを利用して@tweetsを定義しましょう
作業ファイル:app/controllers/users_controller
ヒント:現在ログイン中のユーザーがつぶやいたツイート達を取得するよう書きます
1 2 3 4 5 6 |
class UsersController < ApplicationController
def show
@nickname = current_user.nickname
@tweets = アソシエーションを使用して記述
end
end
|
【 問題1の解答を確認する 】
要点チェック