【Ruby on Rails】デバッグ（binding.pry）

# 目標
binding.pryの使い方をマスターする

# 開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina

# 前提
※　▶◯◯　を選択すると、説明等が出てきますので、
　　よくわからない場合の参考にしていただければと思います。


今回は投稿に対するコメント機能まで実装している例を参考に解説していきます。

- [deviseでログイン環境構築](https://qiita.com/japwork/items/275110b810965fbdf72f)
- [ログインユーザーのみができる投稿機能](https://qiita.com/japwork/items/8dfb52121036791ac4fb)
- [投稿の編集機能（更新、削除）](https://qiita.com/japwork/items/e258ccbbe4f48ea5a3b5)
- [コメント機能実装](https://qiita.com/japwork/items/b2a7e61379c88a5e60c8)

# 流れ
1 デバッグとは？
2 gem 'pry-byebug'のインストール
3 controllerで使用
4 viewで使用


# デバッグとは？
エラーの原因（エラーが出ない場合もあります）を調査して、
理想の動作を実現させるために行うことをデバッグと言います。

アプリケーションがエラーを起こした際には、
基本的にエラーメッセージが出力されるようになっています。
そのエラーメッセージを確認し、デバッグを行い、エラー原因を解決していきます。

今回はその方法の一つでもあるbinding.pryをご紹介します。

# gem 'pry-byebug'のインストール
```rb:gemfile
gem 'pry-byebug'
```
```:ターミナル
$ bundle install
```
<details><summary>補足【pry-byebug】</summary>
記述を加えた場所でプログラムの処理を止め、
その時の状態を確認することができるgemです。</details>

# controllerで使用
処理を止めたい場所で下記を記述。

```rb:
binding.pry
```

## 実際の使用例①
```rb:ターミナル
  def show
    @post = Post.find(params[:id])
    @comment = Comment.new
    @comments = @post.comments
  end
```
上記のような記述があった場合、下記のように追加します。

```rb:ターミナル
  def show
    binding.pry
    @post = Post.find(params[:id])
    @comment = Comment.new
    @comments = @post.comments
  end
```
その後railsサーバーを立ち上げてください。
すると記述したページに遷移すると画面がフリーズするはずです。
その状態のまま、ターミナルに戻ってください。すると下記のようになっています。

```rb:ターミナル
    31: def show
 => 32:   binding.pry
    33:   @post = Post.find(params[:id])
    34:   @comment = Comment.new
    35:   @comments = @post.comments
    36: end

[1] pry(#<PostsController>)> 
```
この状態で[1] pry(#<PostsController>)> の後ろにparamsと入力後、Enterを押してみてください。
postのパラメーターとしてid=32が取得出来ていることがわかります。

```rb:ターミナル
    31: def show
 => 32:   binding.pry
    33:   @post = Post.find(params[:id])
    34:   @comment = Comment.new
    35:   @comments = @post.comments
    36: end

[1] pry(#<PostsController>)> params
=> <ActionController::Parameters {"controller"=>"posts", "action"=>"show", "id"=>"32"} permitted: false>
[2] pry(#<PostsController>)> 
```
次にcontroller通りの記述をしてみます。
するとid=32のデータを取得出来ました。

```rb:ターミナル
[1] pry(#<PostsController>)> params
=> <ActionController::Parameters {"controller"=>"posts", "action"=>"show", "id"=>"32"} permitted: false>
[2] pry(#<PostsController>)> Post.find(params[:id])
  Post Load (3.4ms)  SELECT  "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT ?  [["id", 32], ["LIMIT", 1]]
  ↳ (pry):2
=> #<Post:0x00007f16b08cfeb0
 id: 32,
 user_id: 2,
 title: "test",
 body: "test",
 created_at: Tue, 08 Sep 2020 06:36:21 UTC +00:00,
 updated_at: Tue, 08 Sep 2020 06:36:21 UTC +00:00,
 post_image_id: nil>
[3] pry(#<PostsController>)> 
```
続けてこの投稿に対してのコメントを見る場合、下記のように記述します。
するとid=32に紐づくコメント情報を取得できました。

```rb:ターミナル
[3] pry(#<PostsController>)> Post.find(params[:id]).comments
  CACHE Post Load (0.0ms)  SELECT  "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT ?  [["id", 32], ["LIMIT", 1]]
  ↳ (pry):3
  Comment Load (2.6ms)  SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = ?  [["post_id", 32]]
  ↳ app/controllers/posts_controller.rb:32
=> [#<Comment:0x00007f16b0af5398
  id: 9,
  user_id: 2,
  post_id: 32,
  comment: "",
  created_at: Thu, 17 Sep 2020 09:52:01 UTC +00:00,
  updated_at: Thu, 17 Sep 2020 09:52:01 UTC +00:00,
  score: 1>]
[4] pry(#<PostsController>)> 
```
求めていたパラメーターが返ってきたら成功です。
もし返ってこなければ、記述が間違えているため、見直しが必要です。
※終了する場合は  exit  と入力後、Enterです。

## 実際の使用例②
①では一番上にしましたが、今度は一番下にしてみます。

```rb:ターミナル
  def show
    @post = Post.find(params[:id])
    @comment = Comment.new
    @comments = @post.comments
    binding.pry
  end
```
その後railsサーバーを立ち上げてください。
すると記述したページに遷移すると画面がフリーズするはずです。
その状態のまま、ターミナルに戻ってください。すると下記のようになっています。

```rb:ターミナル
    31: def show
    32:   @post = Post.find(params[:id])
    33:   @comment = Comment.new     
    34:   @comments = @post.comments
 => 35:   binding.pry
    36: end
```
そこで@postを記述すると、上記Post.find(params[:id])の記述と同じ結果が返ってきます。

```rb:ターミナル
[1] pry(#<PostsController>)> @post
=> #<Post:0x00007fc2b06fc870
 id: 32,
 user_id: 2,
 title: "test",
 body: "test",
 created_at: Tue, 08 Sep 2020 06:36:21 UTC +00:00,
 updated_at: Tue, 08 Sep 2020 06:36:21 UTC +00:00,
 post_image_id: nil>
[2] pry(#<PostsController>)> 
```

このようにbinding.pryを置く場所によって調べたい項目を変更できるため、
色々試してみるのもおすすめです。
※終了する場合は  exit  と入力後、Enterです。

## 実際の使用例③
binding.pryはif文などでも使えます。
[2] pry(#<PostsController>)> if @post.nil?　と入力すると
[2] pry(#<PostsController>)*　と表示が変わるため、
１行づつif文の中身を記述していきます。

```rb:
[2] pry(#<PostsController>)> if @post.nil?
[2] pry(#<PostsController>)*   redirect_to new_post_path
[2] pry(#<PostsController>)* else  
[2] pry(#<PostsController>)*   @post
[2] pry(#<PostsController>)* end  
=> #<Post:0x00007fc2b06fc870
 id: 32,
 user_id: 2,
 title: "test",
 body: "test",
 created_at: Tue, 08 Sep 2020 06:36:21 UTC +00:00,
 updated_at: Tue, 08 Sep 2020 06:36:21 UTC +00:00,
 post_image_id: nil>
[3] pry(#<PostsController>)> 
```
※終了する場合は  exit  と入力後、Enterです。
※表示が多い場合は途中まで表示されますが、Enterで取得していくことができ、
取得を終了する場合はqを押すことで終了します。

# viewで使用
viewで使用する場合は、調べたい箇所で下記のように記述します。

```erb:
<% binding.pry %>
```
使い方に関してはcontrollerと同様です。
使うタイミングはeach文の中身を確認するときなどで使います。


# まとめ
binding.pryは使い方次第で開発スピードを格段に早めてくれます。
とくに初学者の方にとっては早めに学ぶことができれば、理解もしやすくなるので
早めの学習をおすすめします。