LoginSignup
15
36

More than 3 years have passed since last update.

【Ruby on Rails】検索機能(モデル、方法選択式)

Posted at

目標

search.gif

開発環境

ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina

前提

※ ▶◯◯ を選択すると、説明等が出てきますので、
  よくわからない場合の参考にしていただければと思います。

流れ

1 controllerの作成
2 routingの編集
2 viewの作成

今回はモデルを選択して検索する方法で進めます。

controllerの作成

ターミナル
$ rails g controller searchs
app/controllers/searchs.controller.rb
class SearchsController < ApplicationController
  def search
    @model = params["model"]
    @content = params["content"]
    @method = params["method"]
    @records = search_for(@model, @content, @method)
  end

  private
  def search_for(model, content, method)
    if model == 'user'
      if method == 'perfect'
        User.where(name: content)
      else
        User.where('name LIKE ?', '%'+content+'%')
      end
    elsif model == 'post'
      if method == 'perfect'
        Post.where(title: content)
      else
        Post.where('title LIKE ?', '%'+content+'%')
      end
    end
  end
end

補足を追加したコードは下記になります。

app/controllers/searchs.controller.rb
class SearchsController < ApplicationController
  def search
    # viewのform_tagにて
    # 選択したmodelの値を@modelに代入。
    @model = params["model"]
    # 選択した検索方法の値を@methodに代入。
    @method = params["method"]
    # 検索ワードを@contentに代入。
    @content = params["content"]
    # @model, @content, @methodを代入した、
    # search_forを@recordsに代入。
    @records = search_for(@model, @content, @method)
  end

  private
  def search_for(model, content, method)
    # 選択したモデルがuserだったら
    if model == 'user'
      # 選択した検索方法がが完全一致だったら
      if method == 'perfect'
        User.where(name: content)
      # 選択した検索方法がが部分一致だったら
      else
        User.where('name LIKE ?', '%'+content+'%')
      end
    # 選択したモデルがpostだったら
    elsif model == 'post'
      if method == 'perfect'
        Post.where(title: content)
      else
        Post.where('title LIKE ?', '%'+content+'%')
      end
    end
  end
end


routingの編集

config/routes.rb
get '/search', to: 'searchs#search'

viewの作成

今回は部分テンプレートを活用。
下記部分テンプレートは<%= render 'searchs/form' %>で使用可能。

検索BOXの部分テンプレート

app/views/searchs/_form.html.erb
<% if user_signed_in? %>
    <%= form_tag(search_path, method: :get) do %>
      <%= text_field_tag 'content' %>
      <%= select_tag 'model', options_for_select({ "User" => "user", "Post" => "post" }) %>
      <%= select_tag 'method', options_for_select({ "完全一致" => "perfect", "部分一致" => "partial" }) %>
      <%= submit_tag '検索' %>
    <% end %>
<% end %>

補足【form_tag】
簡単に入力フォームに必要なHTMLを作成することが可能なヘルパーメソッド。

今回の設置場所。

app/views/homes/mypage
...

<%= render 'searchs/form' %>

...

検索結果の表示画面

app/views/searchs/search.html.erb
<% if @model == 'user' %>
  <h3>【Usersモデルの検索結果】検索ワード:<%= @content %></h3>
  <%= render 'users/index', users: @records %>
<% else @model == 'posts' %>
  <h3>【Postsモデルの検索結果】検索ワード:<%= @content %></h3>
    <%= render 'posts/index', posts: @records %>
<% end %>

部分テンプレートの中身

app/views/posts/_index.html.erb
<table>
    <thead>
        <tr>
            <th>投稿者名</th>
            <th>タイトル</th>
            <th>本文</th>
            <th></th>
            <th></th>
            <th></th>
        </tr>
    </thead>
    <tbody id="post">
    <% posts.each do |post| %>
      <tr>
        <td><%= post.user.name %></td>
        <td><%= post.title %></td>
        <td><%= post.body %></td>
        <td><%= link_to "詳細", post_path(post) %></td>
        <% if post.user == current_user %>
          <td><%= link_to "編集", edit_post_path(post) %></td>
          <td><%= link_to "削除", post_path(post), method: :delete, remote: true %></td>
        <% else %>
          <td></td>
          <td></td>
        <% end %>
      </tr>
    <% end %>
    </tbody>
</table>
app/views/books/_users.html.erb
<% users.each do |user| %>
  <%= link_to user_path(user) do %>
    <%= user.name %><br>
  <% end %>
<% end %>
15
36
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
15
36