Rails 5.2 で簡単なWikiサイトを作る - Part5
Rails 5.2 で簡単なWikiサイトを作る - ajaxを使ったモーダルウィンドウUXの続きです。
環境
Rails 5.2.2
ruby 2.5.1p57
psql (PostgreSQL) 10.4
前提条件
本記事では、Rails、ruby、PGのインストールの内容を含みません。
CSSフレームワークは、bulmaを利用してます。
bulmaを導入する方法はこちら!
Railsアプリケーションにbulmaを導入する
こちらの記事をご確認ください。
はじめに
検索ページを作る
ルーティングの確認
./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
$ 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内を部分一致で複数検索(スペースで分割)するようにします。
./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の設定
コンポーネントの設定
検索フォームの作成
$ 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}
./frontend/components/content-search-form/content-search-form.js
import "./content-search-form.css"
./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>
./frontend/components/content-search-form/content-search-form.css
.content-search-form--hero-body {
padding-bottom: 0;
}
./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();
./app/views/pages/home.html.erb
<%= c("page") do %>
<%= c("content-search-form", search_str: @search_str) %>
<% end %>
検索結果の作成
$ 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}
./frontend/components/content-search-result/content-search-result.js
import "./content-search-result.css"
./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>
./frontend/components/content-search-result/content-search-result.css
.content-search-result {
padding: 3rem 1.5rem;
&--card {
margin-bottom: 1em;
}
}
./app/views/pages/home.html.erb
<%= c("page") do %>
<%= c("content-search-form", search_str: @search_str) %>
+ <%= c("content-search-result", contents: @contents) %>
<% end %>
こんな画面ができました
最後に
Wikiサービス作りました
(小さく告知させてください)
簡単なWiki検索を、社内コミュニケーションチャネルから検索できるツールで、「Poii.io」と言います。