はじめに
検索フォーム(検索窓)を実装する。
仕様
・ヘッダーに検索フォームを追加し、テンプレートを崩さない。
・送信ボタンは実装しない。
・form_withを使用する。
・虫眼鏡マークと検索フォームが重ねる。
・検索キーワードが空白の時は、全ての投稿を返す。
・検索キーワードがタイトルと内容に一致するを記事を検索する。
環境
No | 項目 | 内容 |
---|---|---|
1 | OS | Mac |
2 | Ruby | 2.6.3 |
3 | rails | 6.0.4 |
4 | sass-rails | 5.1.0 |
実装
routes.rbの設定をする
search_pathに対してPost、Getリクエストを設定する。
post '/search', to: 'posts#search'
get '/search', to: 'posts#search'
postモデルを検索するsearchメソッドを実装する
後で設定するpostコントローラーで使用する検索用メソッドを実装する。
・検索キーワードが空白の時は、全ての投稿を返す。
・検索キーワードの前方後方で一致するタイトル、もしくは内容の記事を検索する。
# Postテーブルのcontentカラムを検索する
def self.search(search)
return Post.all unless search
Post.where(['content LIKE(?) OR title LIKE(?)', "%#{search}%", "%#{search}%"])
end
end
ヘッダーに検索フォームのView設定
ヘッダーに検索フォームを追加する。
送信ボタンは実装せず、inputフォームを選択した状態でEnterを押すと検索できる仕様にする。
iタグはfontawesomeから虫眼鏡マークを取得してきた。
...
<div class="search">
<i class="fa-solid fa-magnifying-glass"></i>
<%= form_with(url: search_path, scope: :post, local: true) do |f| %>
<%= f.text_field :search, placeholder: "キーワード検索" %>
<% f.submit %>
<% end %>
</div>
...
Postコントローラーにsearchアクションを設定する
検索結果で下記を表示するため、インスタンス変数を定義して、Viewに渡す。
@keyword: 検索したキーワードを表示
@post_all: キーワードがヒットした記事の数
@posts: paginationする
def search
#Viewのformで取得したパラメータをモデルに渡す
@keyword = params[:post][:search] if params[:post]
@posts_all = Post.search(@keyword)
@posts = Kaminari.paginate_array(@posts_all).page(params[:page]).per(10)
end
if params[:post]
によってnilガードをしている。
検索結果画面でリロードしたときはなにも送信されないので、params[:post]はnilとなり、nilに対して[:search]メソッドすると、エラーになる。
検索結果のViewを設定
検索結果を表示するページを記載する。
<div class="col-md-8">
<h3>検索結果</h3>
<p>
検索キーワード: "<%= @keyword %>" <br>
一致した記事: <%= @posts_all.count %>
</p>
<%= paginate @posts %>
<ul class="posts">
<% @posts.each do |post| %>
<%= render 'posts/post', post: post %>
<% end %>
</ul>
<%= paginate @posts %>
</div>
今回検索フォームと虫眼鏡マークを重ね合わせる仕様にしているため、sassの設定もする。
.search {
float: left;
position: relative;
i {
color: gray;
position: absolute;
left: 10px;
bottom: 5px;
}
input {
border: 1px solid #bbb;
border-radius: 12px;
margin: 13px 5px;
padding-left: 22px;
margin-bottom: 0;
width: 140px;
outline: none;
background-color: #bbb;
&:hover {
opacity: 0.8;
}
}
}
おわりに
これで、検索フォームを実装できた。
参考記事
CSS「position:relative」と「position:absolute」で画像や文字を重ねる方法
railsで検索フォームを作ろう!!