Railsチュートリアル機能拡張【マイクロポスト検索】

Railsチュートリアルで作ったsample_appに機能を拡張していく

今回は、前回に続きRansack Gemを利用してマイクロポスト検索機能を組み込みます。

yukitoku-sw.hatenablog.com


下記の記事を参考にさせていただきました。

https://github.com/activerecord-hackery/ransack

https://qiita.com/YN6127yn/items/fca9efa22536b8b2a9ef


実装

今回はマイクロポストの検索機能を追加するのでstaticpagesのHomeページとusersのShowページの2つを修正します。

コントローラーにRansackを埋め込む

[app/controllers/users_controller.rb]

  def show
    @user = User.find(params[:id])
    redirect_to root_url and return unless @user.activated?
    # @microposts = @user.microposts.paginate(page: params[:page])
    if params[:q] && params[:q].reject { |key, value| value.blank? }.present?
      @q =  @user.microposts.ransack(microposts_search_params)
      @microposts = @q.result.paginate(page: params[:page])
    else
      @q = Micropost.ransack
      @microposts = @user.microposts.paginate(page: params[:page])
    end
    @url = user_path(@user)
  end
[app/controllers/static_pages_controller.rb]
  def home
    if logged_in?
      @micropost = current_user.microposts.build
      # @feed_items = current_user.feed.paginate(page: params[:page])
      if params[:q] && params[:q].reject { |key, value| value.blank? }.present?
        @q = current_user.feed.ransack(microposts_search_params)
        @feed_items = @q.result.paginate(page: params[:page])
      else
        @q = Micropost.ransack
        @feed_items = current_user.feed.paginate(page: params[:page])
      end
      @url = root_path
    end
  end

micropost_search_paramsは上記2つのファイルで共有できるのでapplication_controllerに記述する

[app/controllers/application_controller.rb]

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  include SessionsHelper

  private

    def microposts_search_params
      params.require(:q).permit(:content_cont)
    end
 .
 .
end

VIewsにsearch_form_forを加える

前回のユーザー検索で作成したフォームをそのまま使おうとしたんですが RoutingErrorが出て上手くいきませんでした。なので、_microposts_html.erbというファイルを作成し、前回のフォームの引数を指定するバージョンを作りました。

コントローラーに@urlを記述していたのはそのためです。

[app/views/shared/_microposts_search.html.erb]

<div class="row">
  <div class="search_form">
    <%= search_form_for @q, url: @url do |f| %>
      <%= f.label :content_cont, 'Micropost Search'%>
      <div class="input-group">
        <%= f.search_field :content_cont, placeholder: "Enter keyword..", class: 'form-control' %>
        <span class="input-group-btn">
          <%= f.submit 'Search', class: "btn btn-primary" %>
        </span>
      </div>
    <% end %>
  </div>
</div>
[app/views/static_pages/_home_logged_in.html.erb]

<div class="row">
  <aside class="col-md-4">
    <section class="user_info">
      <%= render 'shared/user_info' %>
    </section>
    <section class="stats">
      <%= render 'shared/stats' %>
    </section>
    <section class="micropost_form">
      <%= render 'shared/micropost_form' %>
    </section>
  </aside>
  <div class="col-md-8">
    <h3>Micropost Feed</h3>
    <%= render 'shared/microposts_search' %>
    <%= render 'shared/feed' %>
  </div>
</div>
[app/views/users/show.html.erb]

<% provide(:title, @user.name) %>

<div class="row">
(省略)
  <div class="col-md-8">
    <%= render 'follow_form' if logged_in? %>
    <% if @user.microposts.any? %>
      <h3>Microposts (<%= @user.microposts.count %>)</h3>
      <%= render 'shared/microposts_search' %>
      <ol class="microposts">
        <%= render @microposts %>
      </ol>
      <%= will_paginate @microposts %>
    <% end %>
  </div>
</div>

完成

こんな感じです

f:id:yukitoku_sw:20191110001102p:plain

f:id:yukitoku_sw:20191110001126p:plain