はじめに
初学者の学習アウトプットです。
先輩方。
アドバイス、訂正、オススメ記事等ありましたらお願いします。
アソシエーション
railsを学習しているのですがアソシエーションって言葉は覚えて、モデル同士の関係に関連付けをするっていうのは分かったのです。
しかし!!!!!
モデル同士の関連付けしてどうなるの?
何ナノ?アソシエーションそれ美味しいの?
(初心者あるある)っていうことに陥って何となく分かった(分かったつもりになってた)
を抜け出せるように理解したいと思いました。
じゃ、やりましょう!!
アソシエーションを定義する
今回Twitterの簡易版アプリを使用しています。
ツイート(投稿)とユーザーを関連付けさせます。
全てのツイートはいずれかのユーザーが投稿したもので、ユーザーは自分が投稿した複数のツイートを所持していることになります。
モデルクラスにhas_manyやbelongs_to等が定義されてる。
所属する側のテーブルに所属するクラス名_idというカラムが存在する。
class User < ApplicationRecord #Userモデル
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :tweets
end
class Tweet < ApplicationRecord #Tweetモデル
belongs_to :user
end
こいう感じで定義されました。
ここまでは理解ができるのですが次ですね。
次、何が?どうなんの?って、、、
アソシエーションを実装
アソシエーションなしの場合。
tweetsテーブルに対して、user_idがuserのidと等しいレコードを取得しています。
#ターミナルにてrails cコマンド実行
$ 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>]
アソシエーション実装後
Userモデルに「User has many Tweets」の状態のアソシエーションを定義したので、Userモデルのインスタンス.tweetsと記述するだけでそのインスタンスが所持しているツイートを取得することができます。(記述が少なくなってる)
$ 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>]
これを実装すると
class UsersController < ApplicationController
def show
@nickname = current_user.nickname
@tweets = current_user.tweets
end
end
こんな感じになり簡単というか記述が減って綺麗に見えるのでよかった!と思いました。
あと自分でアソシエーションをしっかり組んで自分のアプリに技術を落とし込んでいきたいです。
もっと色んなパターンも他にもあると思うのでそこも勉強が必要かなと。
こちらの記事参考にしました。
【Rails初心者向け】モデル間の関連付け(アソシエーション)まとめ
https://qiita.com/To_BB/items/47d2c7b1bc3513025d7b