Implement the search function with multiple models without using ransack. The search method and search model can be selected from the pull-down menu. The search screen will be implemented directly under the header, and the search result display screen will create a new View. I'm a newcomer about a month after I started studying rails, so please miss any strange expressions or descriptions ... (or point out in the question)
ruby '2.6.3' gem 'rails', '~> 5.2.4', '>= 5.2.4.3' gem'bootstrap-sass','~> 3.3.6' (not required)
Please create User model and Post model in advance. I have implemented Devise.
On the site posted by User, enter the following three inputs in the header, search and transition to the display screen.
① Select User search or post (Book model in my app) search from the pull-down menu (form_with) (2) Select the selection method with the select tag to select exact match, prefix match, suffix match, and partial match. ③ Enter a keyword -Display the search results in View (make it possible to change the display contents of the search results with an if statement)


$ rails g controller Search search
routes.rb
get '/search' => 'search#search'
_header.html.erb
*The code above this line is omitted
<div class="row">
  <div class="col-xs-6 col-xs-offset-3 text-center" style="margin-top: 25px;">
    <% if user_signed_in? %>
      <%= form_with url:search_path, method: :get, local: true do |f| %>
        <%= f.text_field 'search[value]' %>
        <%= f.select 'search[model]', options_for_select({ "User" => "user", "Book" => "book" }) %>
        <%= f.select 'search[how]', options_for_select({ "Perfect matching" => "match", "Prefix match" => "forward", "Backward match" => "backward", "Partial Match" => "partical"  }) %>
        <%= f.submit :"Search" %>
      <% end %>
    <% end %>
  </div>
</div>
 search_controller.rb
class SearchController < ApplicationController
  
  def search
    @model = params["search"]["model"]          #Select model@Assign to model
    @value = params["search"]["value"]          #Searched string(Here value)To@Assign to value
    @how = params["search"]["how"]          #The selected search method how@Assign to how
    @datas = search_for(@how, @model, @value)      #search_Define an instance variable in the argument of for
  end                          #@datas will contain the final search results
  
  private
  def match(model, value)                     #def search_Processing when how is match in for
    if model == 'user'                        #Processing when model is user
      User.where(name: value)                 #Where to find a name that exactly matches the value
    elsif model == 'book'           
      Book.where(title: value)
    end
  end
  
  def forward(model, value)
    if model == 'User'
      User.where("name LIKE ?", "#{value}%")
    elsif model == 'book'
      Book.where("title LIKE ?", "#{value}%")
    end
  end
  
  def backward(model, value)
    if model == 'user'
      User.where("name LIKE ?", "%#{value}")
    elsif model == 'book'
      Book.where("title LIKE ?", "%#{value}")
    end
  end
  
  def partical(model, value)
    if model == 'user'
      User.where("name LIKE ?", "%#{value}%")
    elsif model == 'book'
      Book.where("title LIKE ?", "%#{value}%")
    end
  end
  
  def search_for(how, model, value)    #The information defined in the search action is included in the argument
    case how                              #The process of searching from the conditional branch of when which is the content of how of the search method
    when 'match'
      match(model, value)                 #In the argument of the search method(model, value)Is defined
    when 'forward'                        #For example, if how is match, proceed to def match processing.
      forward(model, value)
    when 'backward'
      backward(model, value)
    when 'partical'
      partical(model, value)
    end
  end
end
#Prefix match
Model name.where("Column name LIKE?", "value%")
#Backward match
Model name.where("Column name LIKE?", "%value")
#Partial Match
Model name.where("Column name LIKE?", "%value%")
I will describe it in views / search / search.html.erb
search.html.erb
<div class="container">
  <div class="col-xs-12">
    <% if @model == "user" %>
    <h2>Users search for '<%= @value %>'</h2>
    <table class="table">
        <thead>
            <tr>
                <th></th>
                <th>Name</th>
                <th>Introduction</th>
            </tr>
        </thead>
    <% @datas.each do |user| %>
        <tbody>
            <tr>
                <th>
                    <%= attachment_image_tag(user, :profile_image, :fill, 40, 40, fallback: "no_image.jpg ", size:'40x40') %>
                </th>
                <th>
                    <%= user.name %>
                </th>
                <th>
                    <%= user.introduction %>
                </th>
            </tr>
        </tbody>
    <% end %>
    <% elsif @model == "book" %>
    <h2>Books search for '<%= @value %>'</h2>
    <table class="table">
        <thead>
            <tr>
                <th></th>
                <th>Title</th>
                <th>Opinion</th>
            </tr>
        </thead>
        <% @datas.each do |book| %>
        <tbody>
            <tr>
                <th>
                    <%= attachment_image_tag(book.user, :profile_image, :fill, 40, 40, fallback: "no_image.jpg ", size:'40x40') %>
                </th>
                <th>
                    <%= book.title %>
                </th>
                <th>
                    <%= book.body %>
                </th>
            </tr>
        </tbody>
        <% end %>
    <% end %>
    </table>
  </div>
</div>
 Recommended Posts