LoginSignup
21
29

More than 5 years have passed since last update.

[Rails] 簡単な検索機能を実装する(関連テーブルの検索、and検索も可)

Posted at

引用

というかこちらを書き直して、自分の経験を元にコメントを記載したものです。
EC-CUBEな日々 RUBY ON RAILSで複数のモデルが絡む検索画面の作り方

実行環境

  • Ruby 2.2.2
  • Rails 4.2.3

やりたいこと

  • views/parents/index に簡単な検索機能を実装する
  • 複数の検索条件をandでつなげる
  • 関連テーブルについても検索を行う

比較的簡単な実装だと思います。
簡単な検索をつくるだけなら負荷はransackと比べると小さいと思います(負荷に関するテストはしていませんがransack自体が重たくなりがちなので)。
orでつなげる検索はこのやり方では出来ませんが、ransackを利用するととても簡単です。

model

こんな関係を用意します。
親 has_many 子

親も子も名前(:name)を持ちます。

親をつくる.rb
rails generate scaffold parent name:string
子をつくる.rb
rails generate scaffold child name:string parent:references
parent.rb
class Parent < ActiveRecord::Base
  has_many :childs
end
child.rb
class Child < ActiveRecord::Base
  belongs_to :parent
end

コード

controller

  • def indexについて
    @search_form.searchは初期値だとMember(null)になるので、初期値の場合のみ上書きします。
    (もっとうまい書き方があれば教えてください)

  • class ParentSearchFormについて
    親に検索に一致する複数の子があった場合、親が複数行表示されてしまうので、子の検索には.uniqをつけて重複を防ぎます。
    (人名だとなかなかありえませんが、例えば「子の年齢がxx歳」や「子の性別がxx」検索する場合は一人の親が検索に一致する複数の子を持つ可能性はあるかと思います)

parents_controller.rb
def index
  @search_form = ParentSearchForm.new(params[:search])
  @parents = @search_form.search
  @parents = Parent.all if @parents == Parent
end

class ParentSearchForm
  include ActiveModel::Model

  attr_accessor  :name, :child_name

  def search
    rel = Parent
    rel = rel.where( name: name ) if name.present?
    rel = rel.joins( :child ).where( "childs.name" => child_name ).uniq if child_name.present?

    rel
  end
end

view

先ほどParentSearchFormで用意したattributeを設定します

views/parents/index.html.erb
<%= form_for @search_form, as: 'search', url: :parents, html: {method: :get} do |f| %>

<%= f.label :name, "親の名前" %>
<%= f.text_field :name %><br>
<%= f.label :child_name, "子の名前" %>
<%= f.text_field :child_name %>

<%= f.submit "検索" %>
<% end %>

この検索フォームで@parentsに検索結果が返ってくるので<% @parents.each do |parent| %>あたりを使って一覧を表示してやれば良いです。

21
29
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
21
29