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

# 目標
![search.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700999/a126f999-9e5e-f80c-913d-e7ee2c86652a.gif)

# 開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina

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

- [deviseでログイン環境構築](https://qiita.com/japwork/items/275110b810965fbdf72f)
- [ログインユーザーのみができる投稿機能](https://qiita.com/japwork/items/8dfb52121036791ac4fb)
- [投稿の編集機能（更新、削除）](https://qiita.com/japwork/items/e258ccbbe4f48ea5a3b5)


# 流れ
1 controllerの作成
2 routingの編集
2 viewの作成

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

# controllerの作成
```:ターミナル
$ rails g controller searchs
```
```rb: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

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

```rb: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の編集
```rb:config/routes.rb
get '/search', to: 'searchs#search'
```

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

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

```erb: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 %>
```
<details><summary>補足【form_tag】</summary>
簡単に入力フォームに必要なHTMLを作成することが可能なヘルパーメソッド。</details>
今回の設置場所。

```erb:app/views/homes/mypage
...

<%= render 'searchs/form' %>

...

```

## 検索結果の表示画面

```erb: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 %>
```
部分テンプレートの中身

```erb: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>
```
```erb:app/views/books/_users.html.erb
<% users.each do |user| %>
  <%= link_to user_path(user) do %>
    <%= user.name %><br>
  <% end %>
<% end %>
```