【Rails】テーブル同士を紐付けする手順を解説していく！

##はじめに
Railsの学習のアウトプットとして簡単な掲示板を作成している際に、「**データの紐付け**」にて躓いたので
「紐付け」を行う目的とその手順について、自分用にまとめてみようと思います！

※「ログイン機能」が実装してある事を前提に解説していきます。

##紐付けとは何ぞや
テーブル同士を関連付ける事で、**テーブル同士でデータを取得**できるようにする作業。


##紐付けをする目的
掲示板作成を例として、上述した二つのテーブルを
・「投稿用のテーブル（**postsテーブル**）」
・「ユーザーのテーブル（**usersテーブル**）」
に置き換えることにする。

例えば
投稿テーブルには、**投稿内容のデータ(カラム名をcontentとする)**が保存され
ユーザーテーブルには、ユーザーの**名前のデータ（カラム名をnameとする）**が保存されているとします。
そうすると以下のように表せます。


**postsテーブル**

|id|content|
|:---:|:---:|
|1|タピオカなう！|
|2|学校めんどい……|

**usersテーブル**

|id|name|
|:---:|:---:|
|1|田中|
|2|鈴木|


しかしながら上記２つのテーブルは別物であるため
投稿内容を見ただけでは、誰がどんな投稿したのかという判別がつきません。

**そうなると今度は、誰がその投稿をしたのかわかるようにさせたい訳です。**

要するにデータの紐付けを行う目的とはこの例で言えば
**誰がどの投稿をしたのかを区別すること**になります。



##紐付けを行う手順
それでは早速、掲示板作成を例として実際に紐付けを行ってみます。
しかし、いきなり紐付けしようとしても、何をどうすれば良いのかサッパリだと思いますから
何をどうしたら良いのか、その思考手順を挙げつつ実装を行っていきます。
<br>
####1.まず、実装したい機能を挙げてみる
　➡︎投稿ごとにユーザーを区別したい。

####2.その機能を明確にしてみる
　➡︎投稿ごとに、誰がその投稿をしたのかわかるように、ユーザー名を表示させる。

####3.Railsにおけるデータのやり取りの仕組みを思い出す
　➡︎ブラウザで何かしらの情報を表示させるためには、該当の**アクション内**で、データベースからデータを取得するための記述をする必要がある。
　➡︎今回は「**投稿に対して**」、その投稿を行った「**ユーザーの情報を**」表示させたいので、**投稿用のアクション内**で、ユーザーのデータを取得すればいい。

例

```ruby:posts_controller.rb
 def #(投稿表示用のアクション名)
  @post = Post.find_by(id: params[:id])

   #ユーザーのデータを取得する処理

 end
```


####4.ユーザーのデータを取得する（？）
　➡︎それでは早速、ユーザーのデータを取得してみます。

例

```ruby:posts_controller.rb
 def #(投稿表示用のアクション名)
   @post = Post.find_by(id: params[:id])
   @user = User.find_by(id: @post.X) #ユーザーのデータを取得する処理
 end
 ```

　➡︎「X」って何だよ…と思ったかと思いますが、何者でもない仮のXだと思ってください。
　➡︎何故仮のXを置いているかと言うと、今のままだと
**Userモデルのidと一致可能な、Postモデルのデータが存在しないため**です。
　➡︎なのでこのXの部分に入れるためのカラムを、新しくpostsテーブルに作成する必要があります。こうして紐付けが始まります！

####5.postsテーブルにカラムを追加
　➡︎「Userモデルのidと一致させるためのid」と言う意味で、「**user_id**」と言うカラム名にします。
　➡︎新しくカラムを追加するためには、「**rails g migration**」コマンドを実行してあげる必要があります。
　➡︎今回はuser_idカラムを、Postモデルに追加するので、以下のようにコマンドを実行します

```:ターミナル
 $ rails g migration AddUserIdToPost user_id:integer
```

　➡︎「db/migrate」ディレクトリ内に、「**（作成した日付の数字羅列）add_user_id_to_post.rb**」ファイルが追加されている事を確認。
　➡︎これで、**Railsのアプリケーションフォルダ内には**ファイルが作成されたので、この変更を**データベースに反映**させます。

```:ターミナル
 $ rails db:migrate
```

　➡︎上記のようにコマンドを実行したら、ターミナルで「**rails dbconsole**」コマンドを実行して、postsテーブルに「**user_id**」カラムが追加されている事を確認してください。

**postsテーブル**

|id|content|user_id|
|:---:|:---:|:---:|
|1|タピオカなう！|
|2|学校めんどい……|

####6.user_idカラムに、ユーザーのidを取得させる
　➡︎もう一度、先ほどの投稿表示用のアクションを確認してみます。

```ruby:posts_controller.rb
 def #(投稿表示用のアクション名)
   @post = Post.find_by(id: params[:id])
   @user = User.find_by(id: @post.user_id) #ユーザーのデータを取得する処理
 end
```
　➡︎新たにカラムを作成したので、仮のXを「**user_id**」に変更しました。
　➡︎ただし、まだこのままでは**user_idカラムは空**のままなので、参照するためのidがありません。
　➡︎なので今から、user_idカラムに、**その投稿をしたユーザーのidを取得**させるための記述を行ます。
　➡︎どうやって取得させるかと言うと、新規投稿アクション内の、newメソッドの引数にuser_idを渡し、user_idに「**ログインしているユーザーのid**」が保存されるようにします。

例

```ruby:posts_controller.rb
 def #(新規投稿アクション名)
   @post = Post.new(
    content: params[:content],
    user_id: @current_user.id #ログインユーザーのidを取得して保存
   )
   #新規投稿保存後の処理 
 end
```

　➡︎これにより、これ以降に新規投稿が行われる度に、**ログインしているユーザーのid**が保存されるようになります。

**postsテーブル**

|id|content|user_id|
|:---:|:---:|:---:|
|1|タピオカなう！||
|2|学校めんどい……||
|3|納豆好き|@current_user.id|
|4|ポンポンポン|@current_user.id|

　➡︎idが1のユーザーが新規投稿を行えば、**その投稿のuser_id**には1が入るし、2のユーザーが新規投稿を行えば2が入ります。
　➡︎これで、ユーザーのidを取得させることができました。

####7.ビューで表示
　➡︎新規投稿するごとにログインユーザーのidが取得されるため、以下のように呼び出すと、「**その投稿を行ったユーザーのid**」と一致する「**Userモデル内のid**」を検索して取得してくれるようになります。

```ruby:posts_controller.rb
 def #(投稿表示用のアクション名)
   @post = Post.find_by(id: params[:id])
   @user = User.find_by(id: @post.user_id) #ユーザーのデータを取得する処理
 end
```

　➡︎これにより紐付けは完了したので、投稿詳細ページで表示していきます。

```ruby:show.html.erb
 <%= @user.name %>
 <%= @post.content %>
```

　➡︎後はこれにCSSなどでスタイリングしてあげれば、投稿に対してユーザー名を表示できるようになるかと思います！

##補足にもならない補足
本来ならば投稿詳細ページにだけでなく、別のページの投稿に対してもユーザーの情報を紐付けする必要があると思います。
そうした場合、他のアクションでユーザーの情報を取得する記述をすることになるため、重複することになります。

同じ記述をするのは好ましくないため、ユーザーの情報を一挙に取得するためのメソッド（**インスタンスメソッド**）を定義する必要があるのですが
インスタンスメソッドに関する解説は、また次回したいと思います。

##まとめ
最後に、**投稿とユーザーについての紐付けを行う手順**をもう一度確認してみましょう。
####1.まず、実装したい機能を挙げてみる
####2.その機能を明確にしてみる
####3.Railsにおけるデータのやり取りの仕組みを思い出す
####4.該当アクション内に、ユーザーのデータを取得する処理を記述してみる（仮）
####5.postsテーブルにカラムを追加
####6.user_idカラムに、ユーザーのidを取得させる
####7.ビューで表示

です！


##最後に
Railsにつきましては、学習を始めて2週間の初学者も初学者ですので
Railsにおけるデータのやり取りについて慣れることが先決と考え、このように遠回りするような理解の仕方を取っています。
おかしな点などありましたら、その都度仰って頂けるととても幸いです。

#参考
[Railsでデータベースカラムの追加を行う方法](https://qiita.com/ryosuketter/items/1aba45161bfffefed68b)
[Progate](https://prog-8.com/)