学習の書き留め プログラミング勉強中

プログラミングで学んだことを日記として残して行こうと思います

今日の学習

今日学んだこと 2020/12/25

クリスマスに何してるんだって? 余計なお世話だ!!(笑

学習項目

マイページの実装を通して、異なるテーブルの紐付け-アソシエーションを学んだ

学習内容

Twitterなどは、全てのツイートがただ乱雑に並んでいるわけではなく、誰がツイートしたのかわかるようになっている。
これは投稿内容を管理するテーブル(以下TweetsTable)ユーザーのテーブル(以下UsersTable)が紐づいているため。
さらに具体的にいうとTweetsTableのuser_idのカラムとUsersTableのidのカラムが紐づいている。

TweetsTableにuser_idを保存する方法

まず、テーブルの紐付けをする前に、TweetsTableに自分のツイート(user_id)を保存する必要がある。
ツイートしているのは誰か、それはまさしくログインしているあなた。 ログインしているユーザーはcurrent_userメソッドで示す事ができ、これはdeviceを利用している場合使う事ができる。
ツイートを保存する際にmergeメソッドを使って、ビューから送られてくる情報が入ったparamsと、current_userメソッドで取得したログイン中ユーザーのidを統合して保存させる。

mergeの記載方法

tweet = { name: "たなか", text: "test", image: "test.jpeg" }
uid = { user_id: current_user.id }
tweet.merge(uid)

異なるテーブルの紐付け-アソシエーション

テーブル同士で関連付けておき、一方のモデルからもう一方のモデルにアクセスできるようへするための概念をアソシエーションという。

定義方法

ユーザー目線からツイートを紐づける場合、一人に対して多数のツイートという構図が成り立つ。
このような「1 対 多数」の関連を示すのがhas_manyメソッド

has_many :tweets (:モデル名-複数形)

対して、ツイート目線から見るとそのツイートには一人のユーザーしか居ないという構図が成り立つ。
このような「1 対 1」関連を示すのがbelongs_toメソッド

belongs_to :user (:モデル名-単数形)

両方とも、関連づけたい models のファイルに記述する。

これでツイートとユーザーが紐づいたので、これを元に各ユーザーのshowページを作れば、各のマイページを作る事ができる。 user のshowページの説明は省きます。。。 ただ、使い方としては、例えばユーザーのアクションで

def show
  user = User.find(params[:id])
  @tweets = user.tweets
end

と定義して、ビューファイルで

<%= @tweets.each do |tweet| %>
<p><%= tweet.text %></p>
<% end %>

と表示すれば、そのユーザーの全てのツイートが表示されます。

パフォーマンス低下を防ぐ

アソシエーションを利用す場合、データベースにアクセスする回数が増える。
理由としてはそのユーザー分データベースにアクセスしようとするため。 これをN+1問題といいincludesメソッドを使い一度のアクセスで、関連モデルをまとめて取得させる。 記述方法
includes(:紐付くモデル名)、引数に関連モデルをシンボルで指定

モデル名.includes(:紐付くモデル名)

まとめ

何を紐づけるかを考えることって大切。