＝は代入だよ。変数は箱だよ。って話【初心者向け解説】

# 概要
プログラミングスクールのメンターをしていて、「記事通りに実装したのにうまく動きません。エラーも出てません」って場合がよくあります。

自分も初心者の頃は愚直に記事通りに実装していたのですが、そこからもう一歩進んで、プログラミングを構造的に理解して実装しよう！という内容です。

そもそものコードの意味や、やってることの意味を理解していきましょう！

# 前提
RailsでWebアプリケーションを作成しています。
実装している機能は以下の通りです。
各機能の解説はここでは省きます。Googleさんに聞いてください！

- 投稿機能
- 一覧表示機能
- 検索機能
- タグ機能
- ページネーション機能

要するに複数個の機能をつけているって状態ですね！

# 実際のコード

```ruby:posts_controller.rb
def index
  @posts = params[:tag_id].present? ? Tag.find(prams[:tag_id]).posts : Post.all 
  @posts = Post.all
  @posts = Post.where("body LIKE ?", "%" + params[:search] + "%") if params[:search]
  @posts = @posts.page(params[:page]).per(5)
end
```

このような感じです！
`tag_id`を使ってでタグ検索をしようとしています。それでうまく動かないって状態ですね。
viewやroutesなどは解説の本筋からそれるため割愛します。

結果から言うと以下の通りに変更すれば、正常に動作します。

```ruby:posts_controller.rb
def index
  @posts = params[:tag_id].present? ? Tag.find(prams[:tag_id]).posts : Post.all 
  @posts = @posts.where("body LIKE ?", "%" + params[:search] + "%") if params[:search]
  @posts = @posts.page(params[:page]).per(5)
end
```
bodyを検索するコードについて、記事や教材には以下のような実装になっています。なぜそれを`Post`ではなく`@posts`に変えなければいけないのでしょうか？

```ruby:posts_controller.rb
def index
  @posts = Post.where("body LIKE ?", "%" + params[:search] + "%") if params[:search]
end
```

以下解説です。

# ＝は代入だよ。変数は箱だよ。
コードの解説の前に、タイトル回収させてください。

```ruby:posts_controller.rb
  @posts = Post.all
```
上記のイメージはこんな感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324819/f12c6808-3eb2-57c4-ae36-ca4d1c7f3edc.png)

箱が変数で、矢印が＝って感じです。
すなわち、`@posts`って名前がついた箱の中に`Post.all`って中身が入ってるってことですね。

# 各行の解説

変更前のコードがなぜ動かないのか解説します！最初と最後の行は解説不要ですね。アクションの定義をしています。

```ruby:posts_controller.rb
def index
  @posts = params[:tag_id].present? ? Tag.find(prams[:tag_id]).posts : Post.all 
  @posts = Post.all
  @posts = Post.where("body LIKE ?", "%" + params[:search] + "%") if params[:search]
  @posts = @posts.page(params[:page]).per(5)
end
```
### 2行目

```ruby:posts_controller.rb
  @posts = params[:tag_id].present? ? Tag.find(prams[:tag_id]).posts : Post.all 
```
ここでは三項演算子を使って`@posts`の中身を作成していますね。
三項演算子とは
`条件 ? trueの場合 : falseの場合`と記述します。
すなわちこの行は

```
もしパラメーターの中にtag_idというものがあったら、
タグを検索してそこに紐づく投稿を取得、なかったら、投稿を全て取得し、
@postsというインスタンス変数の中身に入れる
```
ということです。
これによってタグ検索が実現されます。

### 3行目
```ruby:posts_controller.rb
  @posts = Post.all
```
この行では
単純に`@posts`の中に`Post.all`を代入してますね。
すなわち、`@posts`の中身が書きかわっていることです。
イメージはこんな感じです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324819/ddf225ee-acc8-3274-3555-b142ce7e905a.png)
せっかくタグ検索した結果が上書きされて`@posts`に入ってしまいます。
削除しましょう！

### 4行目
```ruby:posts_controller.rb
  @posts = Post.where("body LIKE ?", "%" + params[:search] + "%") if params[:search]
```
ここでは後置ifを使って条件を付けていますね
やっていることは

```
もしパラメータの中にsearchがあったら投稿全てからbodyというカラムの中のを
searchであいまい検索をして、取得した結果を@postsに入れる
```
これも3行目同様に`@posts`を書き換えてしまっています.
ですが、タグ検索したものを文字列で検索することも考えられますなので、以下のように書き換えます

```ruby:posts_controller.rb
  @posts = @posts.where("body LIKE ?", "%" + params[:search] + "%") if params[:search]
```
こうすることで、`@posts`の中身を再利用して、再代入が可能です。
イメージは以下です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324819/23916138-7c8f-e9fc-209a-49bc42bd566e.png)


### 5行目
ここはうまく`@posts`を再代入できていますね！
解説は省きます。

# 以上です！
少し冗長になってしまったかもしれませんが、これで、プログラミングのイメージをうまく持ってくれたら幸いです！