18
22

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

Railsのform_withを使ってシンプルな検索機能を実装する

Last updated at Posted at 2019-06-28

はじめに

ransackというgemを使えば簡単に検索機能を実装できますが、今回は勉強のために、gemを使わないシンプルな検索機能の作り方を紹介します。

前提として、私の環境は下記の通りです。

Ruby 2.6.3

Rails 5.2.3

目的

検索をしたい任意の文字列と、タスクのタイトルが部分一致するデータの集合を取得する。

今回扱うタスクモデル・コントローラー・ビューをscaffoldで一括生成します。

rails g scaffold task title:string

タスクモデルはこのようになったと思います。

ActiveRecord::Schema.define(version: 2019_06_28_130239) do
  create_table "tasks", force: :cascade do |t|
    t.string "title"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end
end

実装方法

それではタスク一覧tasks#indexに検索機能を実装しています。

まずはviewから作りましょう。form_withヘルパーを使います。
url: tasks_pathと指定することで、ユーザーが入力した文字列をtasks_controllerindexアクションに送ります。
データを取得したいのでmethod: :getを指定しましょう。
また、form_withはデフォルトでajaxを使うようにになっているので、local: :trueと指定して、ajaxを解除しましょう。

form.text_field :searchとすることで、indexアクション側でparams[:search]を使って、入力した文字列を受け取れるようにします。

app/views/tasks/index.html.erb
<%= form_with url: tasks_path, method: :get, local: true do |form| %>
  <%= form.text_field :search %>
  <%= form.submit 'Search', name: nil %>
<% end %>

このような検索欄(テキストフィールド)が表示されていると思います。
スクリーンショット 2019-06-28 22.43.50.png

次にcontrollerを書いていきます。

@tasks.where('title LIKE ?', "%#{params[:search]}%")で、ユーザーが入力した文字列に部分一致するデータを検索し、取得しています。
"%#{params[:search]}%"このように%%で囲むことによって、部分一致の検索を行っています。

app/controllers/tasks_controller.rb
def index
  @tasks = Task.all

  @tasks = @tasks.where('title LIKE ?', "%#{params[:search]}%") if params[:search].present?
end

イメージは次の通りです。
(1) hogeと検索欄に入力し、Searchをクリック
スクリーンショット 2019-06-28 23.02.58.png

(2) titleがhogeに部分一致するタスクを表示
スクリーンショット 2019-06-28 23.03.21.png

ちなみに、where('title LIKE ?', "%#{params[:search]}%")where("title LIKE %#{params[:search]}%")のように直接変数を入れることはSQLインジェクションの危険があるので、避けましょう。

以下はRAILS GUIDESからの引用です。

条件文字列の中に変数を直接置くと、その変数はデータベースに そのまま 渡されてしまいます。これは、悪意のある人物がエスケープされていない危険な変数を渡すことができるということです。このようなコードがあると、悪意のある人物がデータベースを意のままにすることができ、データベース全体が危険にさらされます。くれぐれも、条件文字列の中に引数を直接置くことはしないでください。

以上です。

参考

Active Record クエリインターフェイス - Rails ガイド
Rails セキュリティガイド - Rails ガイド

18
22
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
18
22

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?