73
80

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で検索機能を作って気がついたこと

Last updated at Posted at 2015-02-03

Ruby on Railsの学習として検索機能を作ってみました。
色々と調べて覚えたことをまとめておきます。

Practice 2015-02-03 22-01-45.png

検索画面のURL

条件を指定してデータを検索する画面のURLとアクションをどうしようか考えた記録。

検索画面のRESTfulなURL

検索フォームでもform_forが使える

データベースのテーブルと項目が完全に一致しないフォームであっても、ActiveModelを定義することでform_forに渡すことができます。

検索条件フォームのようにテーブルと完全に同一でないフォームもform_forを使って実装できる

選択項目を生成してくれるヘルパーがある

ラジオボタンやチェックボックスのHTMLを自動生成してくれるヘルパーメソッド

  • collection_select
  • collection_radio_buttons
  • collection_check_boxes
app/views/employees/_find_form.html.erb
<%= form_for @form, url: '/employees', method: :get do |f| %>
  <%= f.collection_select :department_id, Department.all, :id, :name %>
  <%= f.collection_radio_buttons :sex_id, Sex.all, :id, :name %>
  <%= f.collection_check_boxes :favorite_ids, Favorite.all, :id, :name, checked: @form.favorite_ids %>
<% end %>

collection_check_boxeschecked:オプションで値の配列を渡さないと初期表示のチェックが付いてくれませんでした。

選択項目の「指定しない」という項目

ラジオボタンは一度チェックすると、未チェックの状態に戻すことができません。なので、「指定しない」という項目を追加しました。

プルダウンの項目は、collection_selectのオプションでinclude_blank: trueを指定することで空の項目が追加されます。

検索条件を組み立てる処理はmodelに書く

データベースから指定された条件に該当するデータを取得するために、モデルのwhereメソッドに渡す条件を組み立てる処理をコントローラに書くと、if文の連続でグチャグチャしたものが出来上がります。

モデルのscopeメソッドで、ひとつひとつの検索条件に対するクラスメソッドを定義することができます。scopeで定義されたクラスメソッドは、デフォルトでallを返すので、条件が指定された時だけwhereするということがシンプルに実装できます。

app/models/employee.rb
  # nameが空でない場合は氏名を部分一致検索する条件を返す
  # nameが空文字の場合はallが返る
  scope :name_like, -> name { where('name like ?', "%#{name}%") if name.present? }
73
80
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
73
80

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?