1
2

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 3 years have passed since last update.

Railsアプリケーションで投稿検索機能を実装する(whereメソッド)

Last updated at Posted at 2020-09-23

アプリ: ラーメン屋の写真や情報を友達と共有できるSNS
Ruby: 2.6.5
Rails: 5.2.0

viewに検索フォームを設置する

form_withを使って、検索ワードをposts_controllerのsearchアクションに渡します。

app/views/layouts/_header.html.erb
・
・
・
<div class="post_search">
  <%= form_with url: search_posts_path, method: :get, local: true do |f| %>
    <%= f.text_field :search, class: 'form-control', placeholder: "キーワード検索"  %>
    <%= f.button :type => "submit" do %>
      <i class="fas fa-search"></i>
    <% end %>
  <% end %>
</div>
・
・
・

スクリーンショット 2020-09-23 18.54.03.jpg

ルーティング

routes.rb を下記のようにすることで、
/posts/searchというURL(search_posts_path)にgetリクエストを送ることでposts_controllerのsearchアクションにルーティングされます。

config/routes.rb
~
~
resources :posts, only: [:new, :create, :edit, :show, :update, :destroy] do
  get :search, on: :collection
end
~
~

posts_controller

検索ワードに合致する投稿を@postsで定義。

app/controllers/posts_controller.rb
~
~
def search
  @section_title = "「#{params[:search]}」の検索結果"
  @posts = if params[:search].present?
             Post.where(['shop_name LIKE ? OR nearest LIKE ?',
                        "%#{params[:search]}%", "%#{params[:search]}%"])
                 .paginate(page: params[:page], per_page: 12).recent
           else
             Post.none
           end
end
~
~

params[:search]でform_withから渡された検索ワードを受け取ります。
whereメソッドはテーブル内から条件に一致したレコードをすべて返します。
(検索ワードがない場合はPost.noneとし、投稿を取得しないようにしました。)

whereメソッド

whereメソッドでは下記のように

モデル名.where('カラム名 = ?', "値")

第一引数に ? を(プレースホルダーと呼ぶ)、第二引数に条件の値を入れることがあります。
このような書き方をすることで、SQLインジェクションというデータベースのデータを不正に操作する攻撃を防ぐことができるそうです。

whereの第二引数には下記のように

"%#{params[:search]}%"

検索ワードの前後に % を置いています。
こうすることで、「空白文字を含む任意の複数文字列」が検索ワードの前後に含まれても
その文字列を持つレコードを返すことができます。

%二郎%
→ 「二郎」「ラーメン二郎」「つけ麺二郎」「ラーメン二郎八王子店」「二郎歌舞伎町店」
 どれも該当する。

%二郎
→ 「二郎」「ラーメン二郎」「つけ麺二郎」は該当するが、
 「ラーメン二郎八王子店」「二郎歌舞伎町店」は該当しない。

下記のように書くことでshop_nameとnearestという2つのカラムから
検索ワードに該当する文字列を検索し、レコードを返します。

Post.where(['shop_name LIKE ? OR nearest LIKE ?',
            "%#{params[:search]}%", "%#{params[:search]}%"])

あとは@postsをapp/views/posts/search.html.erbで表示させるようにしてください。

こんな感じ

スクリーンショット 2020-09-23 21.33.34.jpg

スクリーンショット 2020-09-23 21.34.05.jpg

参考

【Rails】1つの検索フォームで複数カラムをまたいで検索する方法
【Rails】whereメソッドを使って欲しいデータの取得をしよう!

1
2
0

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
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?