Help us understand the problem. What is going on with this article?

Ruby on Rails 検索機能拡張 (railsチュートリアル)

More than 1 year has passed since last update.

目的

Ruby on Rails チュートリアル 5.0(第4版)で実装したサンプルアプリケーションを元に、検索機能を拡張します。

完成版アプリケーション

実際に検索機能を拡張したアプリケーションを見てみたい方はこちら。
https://fathomless-shore-36670.herokuapp.com/about

開発環境

・Rails 5.0
・cloud9

1.indexページにユーザ検索機能を実装する

最終的なソースコードと確認画面

[View]

users/index.html.erb
<% provide(:title, 'All users') %>
<h1>All users</h1>
<%= will_paginate %>

<!--  検索拡張機能  -->
<p>user search</p>
<%= form_tag(users_path, :method => 'get' ) do %>
  <%= text_field_tag :search %>
  <%= submit_tag 'Search', :name => nil %>
<% end %>

<ul class="users">
  <%= render @users %>
</ul>
<%= will_paginate %>

[Controller]

users_controller.rb
class UsersController < ApplicationController
(中略)
  def index
    @users = User.where(activated: true).paginate(page: params[:page]).search(params[:search])
  end
(中略)
end

[Model]

models/user.rb
class User < ApplicationRecord
(中略)
  def self.search(search) #ここでのself.はUser.を意味する
    if search
      where(['name LIKE ?', "%#{search}%"]) #検索とnameの部分一致を表示。User.は省略
    else
      all #全て表示。User.は省略
    end
  end

  private
(中略)
end

[確認画面]
[検索前]
Users検索前.png

[検索後]
Users検索後.png

実装ステップ

手順を知りたい方は以下のブログを参照ください。
Ruby on Rails 検索機能拡張 (railsチュートリアル)

2.userプロフィールページにマイクロポスト検索機能を実装する

最終的なソースコードと確認画面

[View]

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>

      <!--検索拡張機能  -->
      <p>content serch</p>
      <%= form_tag user_path, :method => 'get' do %>
        <p>
          <%= text_field_tag :search, params[:search] %>
          <%= submit_tag "Search", :name => nil %>
        </p>
      <% end %>

      <ol class="microposts">
        <%= render @microposts %>
      </ol>
      <%= will_paginate @microposts %>
    <% end %>
  </div>
</div>

[Controller]

users_controller.rb
class UsersController < ApplicationController
(中略)
  def show
    @user = User.find(params[:id])
    # 検索拡張機能として.search(params[:search])を追加    
    @microposts = @user.microposts.paginate(page: params[:page]).search(params[:search])
  end
(中略)
end

[Model]

models/micropost.rb
class Micropost < ApplicationRecord
(中略)
  def self.search(search) #ここでのself.はMicropost.を意味する
    if search
      where(['content LIKE ?', "%#{search}%"]) #検索とcontentの部分一致を表示。Micropost.は省略。
    else
      all #全て表示。Micropost.は省略。
    end
  end

  private
(中略)
end

[確認画面]
[検索前]
Show検索前.png

[検索後]
Show検索後.png

実装ステップ

基本的には「1.indexページにユーザ検索機能を実装する」と同様のステップ。
[Model]のwhere(['content LIKE ?', "%#{search}%"])が"name"から"content"になっている点に注意。

3.Homeページにマイクロポスト検索機能を実装する

最終的なソースコードと確認画面

[View]

static_pages/home.html.erb
<% if logged_in? %>
  <%= render 'static_pages/user_logged_in' %>
<% else %>
  <%= render 'static_pages/user_not_logged_in' %>
<% end %>
static_pages/_user_logged_in.html.erb
<div class="row">
(中略)
  <div class="col-md-8">
    <h3>Micropost Feed</h3>

    <!--検索拡張機能  -->
    <p>content serch</p>
    <%= form_tag root_path, :method => 'get' do %>
      <p>
        <%= text_field_tag :search, params[:search] %>
        <%= submit_tag "Search", :name => nil %>
      </p>
    <% end %> 
    <%= render 'shared/feed' %>
  </div>
</div>

[Controller]

static_pages_controller.rb
class StaticPagesController < ApplicationController
  def home
    if logged_in?
      @micropost  = current_user.microposts.build
      # 検索拡張機能として.search(params[:search])を追加 
      @feed_items = current_user.feed.paginate(page: params[:page]).search(params[:search])
    end
  end
(中略)
end

[Model]
「2.userプロフィールページにマイクロポスト検索機能を実装する」から変更なし。

models/micropost.rb
class Micropost < ApplicationRecord
(中略)
  def self.search(search) #ここでのself.はMicropost.を意味する
    if search
      where(['content LIKE ?', "%#{search}%"]) #検索とcontentの部分一致を表示。Micropost.は省略。
    else
      all #全て表示。Micropost.は省略。
    end
  end

  private
(中略)
end

[確認画面]
[検索前]
Home検索前.png

[検索後]
Home検索後.png

実装ステップ

基本的には「1.indexページにユーザ検索機能を実装する」と同様のステップ。

4.リファクタリング

上記で検索機能を3つのviewページへ追加しました。
共通する部分が多いのでリファクタリングします。

users/_search.html.erb
<p><%= yield(:search_name) %></p>
<%= form_tag(yield(:path), method: :get) do %>
  <%= text_field_tag :search, params[:search] %>
  <%= submit_tag 'Search', :name => nil %>
<% end %>
users/index.html.erb
<% provide(:title, 'All users') %>
<% provide(:search_name, 'user search') %>
<% provide(:path, users_path) %>
<h1>All users</h1>

<%= will_paginate %>

<ul class="users">
  <%= render 'users/search' %>  <-- searchパーシャル呼出 -->
  <%= render @users %>
</ul>

<%= will_paginate %>
users/show.html.erb
<% provide(:title, @user.name) %>
<% provide(:search_name, 'content search') %>
<% provide(:path, user_path) %>
<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 'users/search' %>   <-- searchパーシャル呼出 -->
      <ol class="microposts">
        <%= render @microposts %>
      </ol>
      <%= will_paginate @microposts %>
    <% end %>
  </div>
</div>
static_pages/_user_logged_in.html.erb
<% provide(:search_name, 'content search') %>
<% provide(:path, root_path) %>
  <div class="row">
(中略)
    <div class="col-md-8">
      <h3>Micropost Feed</h3>
      <%= render 'users/search' %>  <-- searchパーシャル呼出 -->  
      <%= render 'shared/feed' %>
    </div>
  </div>

参考

Simple Search Form in Rails 5

関連記事

Ruby on Rails チュートリアル 完全攻略 概要と演習解答総まとめ
http://mochikichi.hatenablog.com/entry/rails_tutorial_guide

mochikichi321
webエンジニア × ブログ × パパ / 未経験からエンジニアを目指す方を応援 / 大手メーカ9年勤務 → 息子誕生 → 半年間の育休中にプログラミング独学 → 30代未経験からエンジニアへ (上京) / エンジニア転職体験談など "リアル" な情報を発信。
http://mochikichi.hatenablog.com/
tabelog
お店選びで失敗したくない人のためのグルメサイト「食べログ」を開発しています
https://tabelog.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした