[Ruby on Rails] Search function (model, method selection formula)

Target

search.gif

Development environment

ruby 2.5.7 Rails 5.2.4.3 OS: macOS Catalina

Premise

-Build login environment with devise -Posting function that only logged-in users can do -Post editing function (update, delete)

flow

1 Create controller 2 Editing routing 2 Create view

This time, we will proceed by selecting a model and searching.

Creating a controller

Terminal


$ 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

The code with the supplement added is as follows.

rb:app/controllers/searchs.controller.rb


class SearchsController < ApplicationController
  def search
    #view form_At tag
    #The value of the selected model@Assigned to model.
    @model = params["model"]
    #The value of the selected search method@Assign to method.
    @method = params["method"]
    #Search word@Assign to content.
    @content = params["content"]
    # @model, @content, @Substituted method,
    # search_for@Assign to records.
    @records = search_for(@model, @content, @method)
  end

  private
  def search_for(model, content, method)
    #If the selected model is user
    if model == 'user'
      #If the selected search method is an exact match
      if method == 'perfect'
        User.where(name: content)
      #If the selected search method is a partial match
      else
        User.where('name LIKE ?', '%'+content+'%')
      end
    #If the selected model is post
    elsif model == 'post'
      if method == 'perfect'
        Post.where(title: content)
      else
        Post.where('title LIKE ?', '%'+content+'%')
      end
    end
  end
end


Edit routing

config/routes.rb


get '/search', to: 'searchs#search'

Create view

This time, I used a partial template. The following partial template can be used with <% = render'searchs / form'%>.

Search BOX partial template

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 matching" => "perfect", "Partial Match" => "partial" }) %>
      <%= submit_tag 'Search' %>
    <% end %>
<% end %>
Supplement [form_tag] A helper method that allows you to easily create the HTML required for the input form. This installation location.

app/views/homes/mypage


...

<%= render 'searchs/form' %>

...

Search result display screen

erb:app/views/searchs/search.html.erb


<% if @model == 'user' %>
  <h3>[Users model search results] Search word:<%= @content %></h3>
  <%= render 'users/index', users: @records %>
<% else @model == 'posts' %>
  <h3>[Posts model search results] Search word:<%= @content %></h3>
    <%= render 'posts/index', posts: @records %>
<% end %>

Contents of partial template

erb:app/views/posts/_index.html.erb


<table>
	<thead>
		<tr>
			<th>Posted by name</th>
			<th>title</th>
			<th>Text</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 "Details", post_path(post) %></td>
        <% if post.user == current_user %>
          <td><%= link_to "Edit", edit_post_path(post) %></td>
          <td><%= link_to "Delete", 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 %>

Recommended Posts