Rails 5.2 + Bulmaで検索ページを作る

**[Rails 5.2 で簡単なWikiサイトを作る](https://qiita.com/fukmaru/items/318bc4ef1fa5b80e4c9a) - Part5**

[Rails 5.2 で簡単なWikiサイトを作る - ajaxを使ったモーダルウィンドウUX](https://qiita.com/fukmaru/items/9f59511463dded5e0ec1)の続きです。

# 環境

- `Rails 5.2.2`
- `ruby 2.5.1p57`
- `psql (PostgreSQL) 10.4`

# 前提条件

本記事では、Rails、ruby、PGのインストールの内容を含みません。

- ruby のインストールは、[こちら](https://qiita.com/Alex_mht_code/items/d2db2eba17830e36a5f1)の記事がわかりやすかったです。
- Ruby on Rails のインストールは、[こちら](https://qiita.com/yoshiokatsuneo@github/items/d75d4fef9e75afb65126#rails%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB)の記事がわかりやすかったです。

## CSSフレームワークは、bulmaを利用してます。
bulmaを導入する方法は[こちら](https://qiita.com/fukmaru/items/cd9c1c9c8658ac4a0a89#_reference-cab064a3295de148dcde)!

## Railsアプリケーションにbulmaを導入する

[こちら](https://qiita.com/fukmaru/items/cd9c1c9c8658ac4a0a89)の記事をご確認ください。

# はじめに

[git commit log](https://github.com/fukmaru/wiki/commit/24fa3604fd8b6df5c52297e1ca3f2b700b066ed3)

# 検索ページを作る

ルーティングの確認

```rb:./config/routes.rb
Rails.application.routes.draw do
  resources :contents
  root to: "pages#home"
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
```

```bash
$ rails routes
                   Prefix Verb   URI Pattern                                                                              Controller#Action
                 contents GET    /contents(.:format)                                                                      contents#index
                          POST   /contents(.:format)                                                                      contents#create
              new_content GET    /contents/new(.:format)                                                                  contents#new
             edit_content GET    /contents/:id/edit(.:format)                                                             contents#edit
                  content GET    /contents/:id(.:format)                                                                  contents#show
                          PATCH  /contents/:id(.:format)                                                                  contents#update
                          PUT    /contents/:id(.:format)                                                                  contents#update
                          DELETE /contents/:id(.:format)                                                                  contents#destroy
                     root GET    /                                                                                        pages#home
       rails_service_blob GET    /rails/active_storage/blobs/:signed_id/*filename(.:format)                               active_storage/blobs#show
rails_blob_representation GET    /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
       rails_disk_service GET    /rails/active_storage/disk/:encoded_key/*filename(.:format)                              active_storage/disk#show
update_rails_disk_service PUT    /rails/active_storage/disk/:encoded_token(.:format)                                      active_storage/disk#update
     rails_direct_uploads POST   /rails/active_storage/direct_uploads(.:format)                                           active_storage/direct_uploads#create
```

今回は、`/`で、検索画面を作っていきます。アクションとして、 `PagesController#home` を指定しました。

## Controllerの設定

ActiveRecordを用いて、body内を部分一致で複数検索（スペースで分割）するようにします。

```rb:./app/controllers/pages_controller.rb
class PagesController < ApplicationController
  def home
    @contents = Content.where(is_published: true)

    search_params = params.dig("s")
    if search_params
      search_params_arr = search_params.split
      @contents = @contents.where("body ~~* any(array[#{search_params_arr.map{ |i|  %Q('%#{i}%') }.join(',')}])") if search_params_arr.present?
    end

    @search_str = search_params
  end
end
```

## Viewの設定

### コンポーネントの設定

**検索フォームの作成**

```bash
$ mkdir -p frontend/components/content-search-form
$ touch frontend/components/content-search-form/{_content-search-form.html.erb,content-search-form.css,content-search-form.js}
```

```js:./frontend/components/content-search-form/content-search-form.js
import "./content-search-form.css"
```

```erb:./frontend/components/content-search-form/_content-search-form.html.erb
<section class="content-search-form js-content-search-form hero">
  <div class="content-search-form--hero-body js-content-search-form--hero-body hero-body">
    <div class="container">
      <h1 class="title">
        コンテンツ検索
      </h1>
      <h2 class="subtitle">
        <%= form_with url: root_path, method: :get, local: true do |form| %>
          <div class="field">
            <div class="control">
              <%= form.text_field :s, value: search_str, class: "input", placeholder: "e.g 会社の住所", autofocus: true %>
            </div>
          </div>

          <%= form.submit style: "display: none;" %>
        <% end %>
      </h2>
    </div>
  </div>
</section>
```

```css:./frontend/components/content-search-form/content-search-form.css
.content-search-form--hero-body {
    padding-bottom: 0;
}
```

```js:./frontend/packs/application.js
import "init";
import "components/page/page"
import "components/contents/contents"
+ import "components/content-search-form/content-search-form"

import Rails from 'rails-ujs';
Rails.start();
```

```erb:./app/views/pages/home.html.erb
<%= c("page") do %>
  <%= c("content-search-form", search_str: @search_str) %>
<% end %>
```

**検索結果の作成**

```bash
$ mkdir -p frontend/components/content-search-result
$ touch frontend/components/content-search-result/{_content-search-result.html.erb,content-search-result.css,content-search-result.js}
```

```js:./frontend/components/content-search-result/content-search-result.js
import "./content-search-result.css"
```

```erb:./frontend/components/content-search-result/_content-search-result.html.erb
<div class="content-search-result js-content-search-result">
  <% contents.each do |content| %>
    <div class="content-search-result--card js-content-search-result--card card">
      <header class="card-header">
        <p class="content-search-result--title js-content-search-result--title card-header-title">
          <%= content.title.truncate(20) %>
        </p>
        <a href="#" class="card-header-icon" aria-label="more options">
      <span class="icon">
        <i class="fas fa-angle-down" aria-hidden="true"></i>
      </span>
        </a>
      </header>
      <div class="card-content">
        <div class="content-search-result--body js-content-search-result--body content">
          <%= content.body.truncate(100) %>
          <br>
          <small>文字数: <%= content.body.present? ? content.body.gsub(" ", "").size : 0 %> |
             <time><%= content.updated_at %></time></small>
        </div>
      </div>
    </div>
  <% end %>
</div>
```

```css:./frontend/components/content-search-result/content-search-result.css
.content-search-result {
    padding: 3rem 1.5rem;

    &--card {
         margin-bottom: 1em;
    }
}
```

```erb:./app/views/pages/home.html.erb
<%= c("page") do %>
  <%= c("content-search-form", search_str: @search_str) %>
+   <%= c("content-search-result", contents: @contents) %>
<% end %>
```

## こんな画面ができました

<img width="921" alt="スクリーンショット 2019-05-04 00.09.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263973/26e5c474-0261-02ef-66a8-ec5dd0fc13c5.png">


# 最後に

[git commit log](https://github.com/fukmaru/wiki/commit/24fa3604fd8b6df5c52297e1ca3f2b700b066ed3)

# Wikiサービス作りました

(小さく告知させてください:ear:)
簡単なWiki検索を、社内コミュニケーションチャネルから検索できるツールで、「[Poii.io](https://www.poii.io)」と言います。