備忘録として、なるべく自分の理解している範囲で、考え方の順序なども記載していく。
railsを触って、数週間なので、初心者の人のために
慣れている人や頭のいい人だと、そんなのわかってるよと言われることまで書いていきます。
間違っていたら教えてください。
devise でログイン機能は追加しており
UserモデルとBookモデルを作っています。
検索フォームをログインしている場合、全てのページに表示させたいので
app/views/layouts/application.html.erb のviewに記載していく。
<% if user_signed_in? %>
<%= form_tag(search_path, method: :get) do %>
<%= select_tag 'range' ,options_for_select([['---選択してください---', ''], ['User', '1'], ['Book', '2']]) %>
<%= select_tag 'search', options_for_select([["前方一致","forward_match"], ["後方一致","backward_match"], ["完全一致","perfect_match"], ["部分一致","partial_match"]]) %>
<%= text_field_tag (:word) %>
<%= submit_tag "検索" %>
<% end %>
<% end %>
全体を
<%= form_tag(search_path, method: :get) do %> と <% end %>でくくって
searchアクションにparamsである'range', 'search',(:word)を飛ばす
<%= select_tag 'range' ,options_for_select([['---選択してください---', ''], ['User', '1'], ['Book', '2']]) %>
これの意味は['User', '1']この[ ]の中のUserを選んだ場合(ドロップダウンリスト)
’1’を'range'というparamsに入れて、コントローラに飛ばすために書いた。
<%= select_tag 'search', options_for_select([["前方一致","forward_match"], ["後方一致","backward_match"], ["完全一致","perfect_match"], ["部分一致","partial_match"]]) %>
これも同様にドロップダウンリストで選べるようにしているのですが
"前方一致"を選んだら"forward_match"を'search'というparamsに入れてsearchコントローラに飛ばすために書いた。
この2つのコードはselectボックスを作るために
select_tag 'paramsを決めてここに書く', options_for_select
params名はなんでも良い。
<%= text_field_tag (:word) %>
これは検索フォームに入力したワードをwordというparamsに入れて上と同様にsearchコントローラに飛ばすために書いた。
つまり3つのparamsをsearchコントローラに飛ばすコードを書いた。
こんな感じのができる。
続いてsearchesコントローラを書いていく
class SearchesController < ApplicationController
def search
@range = params[:range]
search = params[:search]
word = params[:word]
if @range == '1'
@user = User.search(search,word)
else
@book = Book.search(search,word)
end
end
end
viewページから飛ばした3つのparamsをそれぞれインスタンス変数かローカル変数の中に入れるために
@range = params[:range]
search = params[:search]
word = params[:word]
を書いた。
searchとwordをローカル変数にしたのはmodelのメソッド(今回だとUserモデルとBookモデル)で利用するため、インスタンス変数じゃなくていいから。
if @range == '1'
@user = User.search(search,word)
else
@book = Book.search(search,word)
end
1をユーザーが選んだ場合、
@userをviewページで反映させ、2を選んだら@bookを反映させる条件分岐。
ここで.search(search,word)という searchメソッドを定義しなければいけない。
これはモデルで定義していく。
モデルについて
以下がモデルに検索のメソッドを定義する部分です。
ドロップダウンリストでUserを選んだ場合、
Userモデルにsearchメソッドを書いて、それをsearchコントローラーで呼べるようにする。
app/models/user.rb
def self.search(search,word)
if search == "forward_match"
@user = User.where("name LIKE?","#{word}%")
elsif search == "backward_match"
@user = User.where("name LIKE?","%#{word}")
elsif search == "perfect_match"
@user = User.where("#{word}")
elsif search == "partial_match"
@user = User.where("name LIKE?","%#{word}%")
else
@user = User.all
end
end
この書き方はググって出てきたものを真似した。
注意点は自分で定義した(search,word)2つのparamsを書くこと
searchにはviewページに書いた
"forward_match"や"backward_match"が入ってきている。
wordにはユーザーが検索フォームに入れたワードが入っている。
User.where("name LIKE?","#{word}%")
このコードはUserモデルから検索ワードにヒットしているかを確認するコードで
nameはUserテーブルのカラム名を記載する。
名前での検索だと思うのでnameにしてある
続いて、ユーザーBookを選んだ場合のメソッドをBookモデルに書いていく
def self.search(search, word)
if search == "forward_match"
@book = Book.where("title LIKE?","#{word}%")
elsif search == "backward_match"
@book = Book.where("title LIKE?","%#{word}")
elsif search == "perfect_match"
@book = Book.where("#{word}")
elsif search == "partial_match"
@book = Book.where("title LIKE?","%#{word}%")
else
@book = Book.all
end
end
Userモデルと同様の書き方にする
そして検索結果を表示するviewページを作成
今回はsearchesフォルダにsearch.index.html.erbを作成したので
routes.rbに
get 'search' => 'searches#search'
を追記した。
続いて
search.html.erbには
<h2>Results index</h2>
<!--books一覧 -->
<table class="table table-hover table-inverse">
<% if @range == '2' %>
<thead>
<tr>
<th></th>
<th>Title</th>
<th>Opinion</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @book.each do |book| %>
<tr>
<td>
<%= link_to(book.user) do %>
<%= attachment_image_tag(book.user, :profile_image, :fill, 50, 50, fallback: "no-image-mini.jpg") %>
<% end %>
</td>
<td>
<%= link_to book.title, book, class: "book_#{book.id}" %>
</td>
<td><%= book.body %></td>
</tr>
<% end %>
</tbody>
<% else %>
<thead>
<tr>
<th>image</th>
<th>name</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @user.each do |user| %>
<tr>
<td><%= attachment_image_tag(user, :profile_image, :fill, 50, 50, fallback: "no-image-mini.jpg") %></td>
<td><%= user.name%></td>
<td><%= link_to "Show", user, class: "user_#{user.id}" %></td>
</tr>
<% end %>
</tbody>
<% end %>
</table>
終わりに
以上が検索機能の実装方法になります。
疑問、気になるところがございましたら、質問、コメントよろしくお願いします!!!