2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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

Last updated at Posted at 2022-01-28

概要

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

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

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

前提

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

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

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

実際のコード

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などは解説の本筋からそれるため割愛します。

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

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に変えなければいけないのでしょうか?

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

以下解説です。

=は代入だよ。変数は箱だよ。

コードの解説の前に、タイトル回収させてください。

posts_controller.rb
  @posts = Post.all

上記のイメージはこんな感じです。

image.png

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

各行の解説

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

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行目

posts_controller.rb
  @posts = params[:tag_id].present? ? Tag.find(prams[:tag_id]).posts : Post.all 

ここでは三項演算子を使って@postsの中身を作成していますね。
三項演算子とは
条件 ? trueの場合 : falseの場合と記述します。
すなわちこの行は

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

ということです。
これによってタグ検索が実現されます。

3行目

posts_controller.rb
  @posts = Post.all

この行では
単純に@postsの中にPost.allを代入してますね。
すなわち、@postsの中身が書きかわっていることです。
イメージはこんな感じです
image.png
せっかくタグ検索した結果が上書きされて@postsに入ってしまいます。
削除しましょう!

4行目

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

ここでは後置ifを使って条件を付けていますね
やっていることは

もしパラメータの中にsearchがあったら投稿全てからbodyというカラムの中のを
searchであいまい検索をして、取得した結果を@postsに入れる

これも3行目同様に@postsを書き換えてしまっています.
ですが、タグ検索したものを文字列で検索することも考えられますなので、以下のように書き換えます

posts_controller.rb
  @posts = @posts.where("body LIKE ?", "%" + params[:search] + "%") if params[:search]

こうすることで、@postsの中身を再利用して、再代入が可能です。
イメージは以下です。
image.png

5行目

ここはうまく@postsを再代入できていますね!
解説は省きます。

以上です!

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

2
1
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?