読者です 読者をやめる 読者になる 読者になる

試される大地から

furaiboが送る技術ブログ。プログラミングのTipsなど書いていきます。

Ruby on Railsで検索フォームを作る方法


こんにちは、furaiboです。


以前の記事で、Rubyを使って、歌詞サイトから歌詞を取ってくるスクリプトについての説明をしました。

Rubyを使って歌詞サイトから歌詞を取得する方法 - 試される大地から



こうしたスクリプトを活用してRuby on Railsによる歌詞検索サイト(※一般非公開)を構築しましたので、その時に得た、検索フォームの作成のノウハウについてのお話をしたいと思います。





今回作成するときのマイグレーションのクラスの名称はLyricとします。Lyricクラスは、title, pronounce, singer, lyricist, composer, arranger, lyricフィールドをもつものとします。


このときにRailsで構築を行うと、viewsディレクトリ内のindex.html.erb、そしてmodelディレクトリ内にlyric.rbがデフォルトとしてできます。例えば、indexはこんな感じの画面になります。


f:id:incodethx3932:20140727155351j:plain



データベースに入っているレコードすべてを表示させるだけなので、非常に味気なく、検索もできないのでつまらないですね。自分のアプリケーションにおいて自動生成されたindex.html.erbとlyric.rbのコードは以下のようになっていました。


・index.html.erb

<h1>Listing lyrics</h1>

<table>
  <thead>
    <tr>
      <th>Title</th>
      <th>Pronouce</th>
      <th>Singer</th>
      <th>Lyricist</th>
      <th>Composer</th>
      <th>Arranger</th>
      <th>Lyric</th>
      <th colspan="3"></th>
    </tr>
  </thead>

  <tbody>
    <% @lyrics.each do |lyric| %>
      <tr>
        <td><%= lyric.title %></td>
        <td><%= lyric.pronouce %></td>
        <td><%= lyric.singer %></td>
        <td><%= lyric.lyricist %></td>
        <td><%= lyric.composer %></td>
        <td><%= lyric.arranger %></td>
        <td><%= lyric.lyric %></td>
        <td><%= link_to 'Show', lyric %></td>
        <td><%= link_to 'Edit', edit_lyric_path(lyric) %></td>
        <td><%= link_to 'Destroy', lyric, method: :delete, data: { confirm: 'Are you sure?' } %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<br>

<%= link_to 'New Lyric', new_lyric_path %>


・lyric.rb

class Lyric < ActiveRecord::Base
end




これを以下のように改造してやります。



・index.html.erb

<h1>Lyric Host</h1>

<div id="message">
  <br />
  <p>Lyric Hostへようこそ! 当ページでは、歌詞データを検索することができます。</p>
  <p>歌詞のみの検索では時間がかかることがあります。</p>
  <br />
</div>

<%= form_tag Lyric, :method => 'get' do %>
  <p>
    曲名 : <br />
    <%= text_field_tag :title, params[:title] %><br />
    歌手 : <br />
    <%= text_field_tag :singer, params[:singer] %><br />
    作詞 : <br />
    <%= text_field_tag :lyricist, params[:lyricist] %><br />
    作曲 : <br />
    <%= text_field_tag :composer, params[:composer] %><br />
    編曲 : <br />
    <%= text_field_tag :arranger, params[:arranger] %><br />
    歌詞(歌い出しでなくても可) : <br />
    <%= text_field_tag :lyric, params[:lyric] %><br />
    <%= submit_tag "検索" %>
  </p>
<% end %>

<br />
<p><%= render :text => "#{@search.length}件の楽曲" %></p>

<table>
  <thead>
    <tr>
      <th width="250">曲名</th>
      <th width="250">歌手</th>
      <th width="150">作詞</th>
      <th width="150">作曲</th>
      <th colspan="3"></th>
    </tr>
  </thead>
  
  <br />
  <tbody>
    <% @search.each do |lyric| %>
      <tr>
        <td><%= lyric.title %></td>
        <td><%= lyric.singer %></td>
        <td><%= lyric.lyricist %></td>
        <td><%= lyric.composer %></td>
        <td><%= link_to 'Show', lyric %></td>
      </tr>
    <% end %>
  </tbody>
</table>

<% if @search.size == 0 then %>
<p>該当する曲が存在しません</p>
<% end %>

<br>


・lyric.rb

class Lyric < ActiveRecord::Base

  def self.search(params) #self.でクラスメソッドとしている
    if params # 入力がある場合の処理
      data = Lyric.all
      data = data.where(['title LIKE ?', "%#{params["title"]}%"]) if params["title"]
      data = data.where(['singer LIKE ?', "%#{params["singer"]}%"]) if params["singer"]
      data = data.where(['lyricist LIKE ?', "%#{params["lyricist"]}%"]) if params["lyricist"]
      data = data.where(['composer LIKE ?', "%#{params["composer"]}%"]) if params["composer"]
      data = data.where(['arranger LIKE ?', "%#{params["arranger"]}%"]) if params["arranger"]
      data = data.where(['lyric LIKE ?', "%#{params["lyric"]}%"]) if params["lyric"]
      data
    else
      Lyric.all   # 全て表示する
    end
  end

end



非常に簡単です。Lyric.allとすることによって、Lyricクラスのレコードがすべて配列として取得出来ます。さらにwhereやLIKEを使ってあいまい検索も可能になります。whereをつなげてやればすべての条件に合致する検索を簡単に記述できるのです。


皆さんが検索フォームを作る場合にはLyricの部分を自分が定義したものに置き換えてもらえばよいと思います。




そうして実際に出来上がったサイトのビジュアルがこちら。


f:id:incodethx3932:20140727161450p:plain




歌手を「ポルノグラフィティ」、作曲を「ハルイチ」として検索してみます。



f:id:incodethx3932:20140727161823p:plain



ちゃんと検索できています。



このように、Railsをうまく使えば簡単に検索フォームを作ることができます。
Ransackなる簡単に検索フォームを作れるGemもありますが、こうしたGemがなくとも、
自分で検索フォームを作るほうがカスタマイズしやすく、勉強になると思います。



Ruby on Railsの威力、すごいです。