0
0

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 1 year has passed since last update.

【Rails】検索フォームをヘッダーに追加する

Last updated at Posted at 2022-08-16

はじめに

検索フォーム(検索窓)を実装する。
仕様
・ヘッダーに検索フォームを追加し、テンプレートを崩さない。
・送信ボタンは実装しない。
・form_withを使用する。
・虫眼鏡マークと検索フォームが重ねる。
・検索キーワードが空白の時は、全ての投稿を返す。
・検索キーワードがタイトルと内容に一致するを記事を検索する。
タイトルなし.gif

環境

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リクエストを設定する。

routes.rb
    post '/search',  to: 'posts#search'
    get  '/search',  to: 'posts#search'

postモデルを検索するsearchメソッドを実装する

後で設定するpostコントローラーで使用する検索用メソッドを実装する。
・検索キーワードが空白の時は、全ての投稿を返す。
・検索キーワードの前方後方で一致するタイトル、もしくは内容の記事を検索する。

post.rb
  # 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から虫眼鏡マークを取得してきた。

_header.html.erb
...    
<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する

posts_controller.rb
  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を設定

検索結果を表示するページを記載する。

posts/search.html.erb
  <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の設定もする。

custom.scss
.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で検索フォームを作ろう!!

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?