Rails コンソールでDBのデータ確認

_今回は、railsコンソールでDBのデータを取得し確認する方法を学んだので記載致します！_
_まぁ、モデルにデータを突っ込んだ後にデバックして確認出来るので、かなりためにならない記事なるかもしれませんがご勘弁してください(T . T)_
#モデルのプロパティとDBのデータ内容
今回使用するモデルとデータは下記になります。

```user.rb
class User < ApplicationRecord
  has_many :comment
end
#Userクラスのプロパティ
  t.string :user_name
  t.integer :age
```
```comment.rb
class Comment < ApplicationRecord
  belongs_to :user
#Commentクラスのプロパティ
  t.string :text
```
__usersテーブル__

| user_name | age |
|:-:|:-:|
| 山田  | 18  |
| 鈴木  | 20  |
| 田中  | 21  |

__commentsテーブル__

| user_id | text |
|:-:|:-:|
| 1  | 山田コメント１  |
| 1  | 山田コメント２  |
| 2  | 鈴木コメント  |
_（データが適当で申し訳ない）_
#ここからコンソール上での操作になります
##1つのレコードのみ取得
```console
###userテーブルから山田のレコードを取得
user = User.find(1)
###SQLの実行クエリ
 SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
###取得したレコード内容
<id: 1, user_name: "山田", age: 18, created_at: nil, updated_at: nil>
###取得したレコードの年齢のみ表示
user.name
18
```
上記のような操作は、一度は実行したことがあると思います。
内容としては、DBから_「usersテーブルのidが１のレコードを取ってきて」_と命令してインスタンス変数に格納しています。
この変数userには、ハッシュの形でデータが格納されています。
なので、このデータの年齢だけ取り出したい場合は、__「user.age」__と入力すれば
keyになっているagyのバリューである１８のみ取得できます。
##複数レコードの取得
```console
###userテーブル全てを取得
user = User.all
###SQLの実行クエリ
  SELECT `users`.* FROM `users`
###取得したレコード内容
 [#<User:0x00007f8cbb348bf0 id: 1, user_name: "山田", age: 18, created_at: nil, updated_at: nil>,
 #<User:0x00007f8cbb348b28 id: 2, user_name: "鈴木", age: 20, created_at: nil, updated_at: nil>,
 #<User:0x00007f8cbb348a60 id: 3, user_name: "田中", age: 21, created_at: nil, updated_at: nil>]
```
複数のレコードを取得すると多分上記のような形になると思います。
複数レコードのデータを取得した場合、単一レコードを取得した時とデータの形が変わります。
単一のレコード場合はデータの形はハッシュでしたが、複数のレコードの場合は、データの形が配列になります。
配列の中に１レコードづつ入っているイメージだと考えやすいかもしれません。
では、変数userの中に入っている山田さんのレコードのみ表示させる場合と
山田さんの年齢のみ表示させる方法は下記になります。

```console
###山田さんのレコードのみ表示
 user[0]
id: 1, user_name: "hajime", age: 18, created_at: nil, updated_at: nil>
###山田さんの年齢のみ表示
 user[0].age
18
```
山田さんの年齢のみ表示させたい場合は、まず変数userに格納されている配列の0番目を
指定します。
０番目の配列には、山田さんのレコードがハッシュの形で格納されていますので、
データを表示させる場合は__「user[0].age」__

__注意)
DBのレコードにはidで自動採番されている番号がありますが、DBのidには、自動採番の０番目というのは存在しません。
しかし、rubyに限らず配列のプログラムは０番目から始まります。__
##複数のテーブルから紐付くデータを取得

```console
###userテーブル全てを取得
user = User.all.includes(:comment)
###SQLの実行クエリ
  SELECT `users`.* FROM `users`
  SELECT `comments`.* FROM `comments` WHERE `comments`.`user_id` IN (1, 2, 3)
###取得したレコード内容
 [#<User:0x00007f8cbb348bf0 id: 1, user_name: "山田", age: 18, created_at: nil, updated_at: nil>,
 #<User:0x00007f8cbb348b28 id: 2, user_name: "鈴木", age: 20, created_at: nil, updated_at: nil>,
 #<User:0x00007f8cbb348a60 id: 3, user_name: "田中", age: 21, created_at: nil, updated_at: nil>]
```
上記は、__usersテーブル__のユーザに紐付く__commentテーブル__のレコードを一緒に
取得し、変数userに格納しています。
今までと違いSQLの実行クエリが2つになっています。
注)_ここからは、自分のでき悪さにずっと悩んで嫌悪した箇所です(( _ _ ))_
では、今回取得したレコードの中から鈴木さんがコメントしたレコードを表示させます。
注）かなり上方になりますがDBのデータを元に記載しています。

```console
###鈴木さんのコメントしたレコードのみを表示
user[1].comment[0].text
鈴木コメント
###山田さんのコメントしたレコードかつ、2つ目のコメントのみを表示
uset[0].comment[1].text
山田コメント２
```
まず、鈴木さんコメントを表示させる方から説明します。
usersテーブルから複数レコードを取得するとろまでは前回と一緒になりますが、
今回は、usersテーブルのユーザに紐づいたコメントも一緒に取得しているため、
__user.all.includes(:comment)__で__commentテーブル__からも
紐付くレコード取得しています。
ざっくりですが、
このクエリでusersテーブルから全てのレコード取得
__SELECT `users`.* FROM `users`__
usersテーブルから取得したレコードのidが1,2,3に紐付くレコードのみを取得
__SELECT `comments`.* FROM `comments` WHERE `comments`.`user_id` IN (1, 2, 3)__
紐付くレコードは、１件であっても全て配列の形で変数に格納されています。
なので、変数userから鈴木さんのコメントのみを表示させたい場合は、
user配列の１番目の要素の中にさらに配列があり、その配列のハッシュキーtextにアクセスすると
無事に__「鈴木コメント」__が表示されます。
__user[1].comment[0]__
図で表すとこんな感じです。
![スクリーンショット 2021-03-16 22.39.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/518234/d709ebda-0aec-7501-cc8b-36b967d79f74.png)
#まとめ！！
_はぁ😩モヤモヤがやっと解決したが別にこれができたからといって何かメリットが有るのか？と
言われるとないのではないかと思う。
何故ならコントローラで変数をデバッグすれば中身が見れるので、わざわざコンソールでする必要もないかと思った(T . T)_

余談だが、今回userに紐付くレコードなのでuserが１に対してcommentが複数なのでN
N+1問題がなんとなくわかりました。
実はuserに紐付くcommentのレコードは、includesしなくても表示できます。
何故ならマイグレーションファイルでテーブル結合の設定してますからね！
ただし、commentテーブルのレコード取得するたびに、SQLのクエリがは発生するため、パフォーマンスが出ません。
当然ですよね。笑
ユーザ毎にコメントを取得するたびにクエリが走るわけですから。なので、最初からincludesで紐付くレコード全て
取得しておけば最初だけクエリが実行され毎回実行しなくてすみます。
下記はおまけ記事です。
#includesしないパターン
```console
###全てのusersテーブルのレコード取得
 user = User.all ###変数userに格納

###SQLの実行クエリ
SELECT `users`.* FROM `users`

###取得結果
[ id: 1, user_name: "山田", age: 18, created_at: nil, updated_at: nil>,
  id: 2, user_name: "鈴木", age: 20, created_at: nil, updated_at: nil>,
  id: 3, user_name: "田中", age: 21, created_at: nil, updated_at: nil>]

###山田コメントを取得
user[0].comment[0] ###変数userの配列0番目の中の配列0番目ユーザコメントを呼び出し
user[0].comment[1] ###変数userの配列0番目の中の配列1番目ユーザコメントを呼び出し
###SQLの実行クエリ
  SELECT `coments`.* FROM `coments` WHERE `coments`.`user_id` = 1
[ id: 1, text: "山田コメント１", user_id: 1, created_at: nil, updated_at: nil>, 
  id: 2, text: "山田コメント２", user_id: 1, created_at: nil, updated_at: nil> ]

###鈴木コメントを取得
user[1].comment[0] ###変数userの配列0番目の中の配列0番目ユーザコメントを呼び出し
###SQLの実行クエリ
  SELECT `coments`.* FROM `coments` WHERE `coments`.`user_id` = 2
[ id: 1, text: "鈴木コメント", user_id: 2, created_at: nil, updated_at: nil>]
```
ユーザ毎にクエリが発生。
#includesするパターン

```console
###全てのusersテーブルのレコード取得し、さらに紐付くcommentテーブルのレコード取得
 user = User.all.includes(:coment)

###SQLの実行クエリ
SELECT `users`.* FROM `users`
SELECT `coments`.* FROM `coments` WHERE `coments`.`user_id` IN (1, 2, 3)
[id: 1, user_name: "hajime", age: 18, created_at: nil, updated_at: nil>,
 id: 2, user_name: "yuta", age: 20, created_at: nil, updated_at: nil>,
 id: 3, user_name: "kazune", age: 22, created_at: nil, updated_at: nil>]

###山田コメントを取得
user[0].comment[0] ###変数userの配列0番目の中の配列0番目ユーザコメントを呼び出し
###鈴木コメントを取得
user[1].comment[0] ###変数userの配列0番目の中の配列0番目ユーザコメントを呼び出し
SQLのクエリは発生しない。
```
ユーザ毎にクエリは発生しない。