[Rails 6] Implementation of search function

Introduction

I am creating an application that allows you to search and browse articles. This time, I implemented the search function using a gem called'ransack', so I will describe it for memorandum and review.

environment

Ruby on Rails '6.0.0' Ruby '2.6.5'

Premise

The article post (article table) has already been created, and the user can view the article.

What is ransack

It is a gem that can implement a simple search form and also create an advanced search form. By introducing this ransack, the following methods can be used.

--_eq method: Search according to the conditions --_cont method: Partial match --_iteq method: Search condition "less than or equal to"

There are various other search methods, but I will omit them this time.

The official GitHub is here.

① Introduction of gem

Gemfile


gem 'ransack'

Terminal


% bundle install

Install the gem with the above command.

② Routing description

config/routes.rb


(Omitted)
get 'articles/search'

This time, we have implemented the article search function, so we will call it "articles controller". The search function is named "search action".

③ Description of controller (articles)

First, I will describe the whole, and then I will explain partly.

app/controllers/articles_controller.rb


class ArticlesController < ApplicationController
  before_action :search_article, only: [:index, :search]
  def index
    @articles = Article.includes(:user).order('created_at DESC').limit(4)
    @ranks = Article.find(Like.group(:article_id).order('count(article_id) DESC').limit(4).pluck(:article_id))
  end

・ ・ ・(中略)・ ・ ・

  def search
    @results = @a.result(distinct: true).page(params[:page]).per(8).order('created_at DESC')
  end

  private

  def search_article
    @a = Article.ransack(params[:q])
  end
end

app/controllers/articles_controller.rb


  private

  def search_article
    @a = Article.ransack(params[:q])
  end

In this description, I'm looking for article information from the articles table using the key (: q). And it creates a search object named "@a". The method name that performs this process is "search_article", and since it is used only in the index and search actions, it is limited to "only" in before_action.

app/controllers/articles_controller.rb


  def search
    @results = @a.result(distinct: true).page(params[:page]).per(8).order('created_at DESC')
  end

And, for this @a, by setting ".result", the search result is acquired.

--"Distinct: true": Duplicate data can be excluded and acquired --.page (params [: page]) .per (8) .order ('created_at DESC') ": Use pagination of gem called kaminari so that 8 articles are displayed in the order of creation on one page. I am.

④ View file description

Search form

ruby:app/views/layouts/_search.html.erb


<%= search_form_for @a, url: articles_search_path do |f| %>
  <div class="search-wrapper">
    <div class="search-content col-12">
        <%= f.label :type_id_eq, 'Select type', class: 'label' %>
        <div class="radio-btn">
          <%= f.radio_button :type_id_eq, '', {checked: true} %>unspecified
          <%= f.radio_button :type_id_eq, 1 %>Subsidies / subsidies
          <%= f.radio_button :type_id_eq, 2 %>Institutional loan
        </div>
    </div>
    <div class="search-content col-12">
        <%= f.label :area_id_eq, 'Select a region', class: 'label' %>
        <%= f.collection_select(:area_id_eq, Area.all, :id, :name, {include_blank: "---"}, {class:"search-select-box float-right"}) %>
    </div>

... (Omitted) ...

    <div class="search-content col-12">
        <%= f.label :title_or_infomation_cont, 'Keyword search', class: 'label' %>
        <%= f.search_field :title_or_information_cont, placeholder: 'Enter a keyword', class:"search-form-control float-right" %>
    </div>
    <div class="search-content col-12 text-center">
      <%= f.submit 'Search by this condition', class:"btn btn-outline-success search-btn" %>
    </div>
  </div>
<% end %>

I will explain partly.

ruby:app/views/layouts/_search.html.erb


<%= search_form_for @a, url: articles_search_path do |f| %>

This is the first line. A search form is generated by passing "@a (search object)" as an argument of search_form_for.

ruby:app/views/layouts/_search.html.erb


   <div class="search-content col-12">
        <%= f.label :type_id_eq, 'Select type', class: 'label' %>
        <div class="radio-btn">
          <%= f.radio_button :type_id_eq, '', {checked: true} %>unspecified
          <%= f.radio_button :type_id_eq, 1 %>Subsidies / subsidies
          <%= f.radio_button :type_id_eq, 2 %>Institutional loan
        </div>
    </div>

--type_id_eq will search for the one that matches (= equal) the one selected with the radio button. type_id is included as an article column. --By setting "checked: true", it will be selected by default.

ruby:app/views/layouts/_search.html.erb


 <div class="search-content col-12">
        <%= f.label :area_id_eq, 'Select a region', class: 'label' %>
        <%= f.collection_select(:area_id_eq, Area.all, :id, :name, {include_blank: "---"}, {class:"search-select-box float-right"}) %>
    </div>

--area_id_eq is also looking for a match area. -<% = f.collection_select ~%> will generate a pull-down. This time, the article posting function has already created an Area model using ActiveHash.

ruby:app/views/layouts/_search.html.erb


 <div class="search-content col-12">
        <%= f.label :title_or_infomation_cont, 'Keyword search', class: 'label' %>
        <%= f.search_field :title_or_information_cont, placeholder: 'Enter a keyword', class:"search-form-control float-right" %>
  </div>

--"Title_or_information_cont": In the column of this article, there is information on title and information, and I am looking for a part of it that matches the keyword (_cont).

Search results

ruby:app/views/articles/search.html.erb


<div class="container">
  <h5 class="article-title"><i class="fas fa-poll-h fa-2x my-orange"></i>Search result list</h5>
    <div class="row">
      <% if @results.length !=0 %>
          <% @results.each do |result| %>
            <div class="card-group col-md-6 col-lg-3">
              <%= link_to article_path(result.id), class: "article-link" do%>
                <span class="article-info"><%= result.genre.name %></span>
              <div class="card articles-chart">
                <%= image_tag result.image, class:"card-img-top" if result.image.attached? %> 
                  <div class="card-body">
                    <h5 class="card-title"><%= result.title %></h5>
                    <p class="card-text"><%= result.information.truncate(30) %></p>
                    <p class="like-button"><i class="far fa-heart fa-2x" style="color: #e82a2a;"></i><span style="color: #e82a2a"><%= result.likes.count %></span></p>
                  </div>
              </div>
              <% end %>
            </div>
          <% end %>
        <% end %>
      <% else %>
        <h5 class="alert">There are no applicable posts!</h5>
      <% end %>
    </div>
</div>

-<% if @ results.length! = 0%>: Conditional bifurcation is performed depending on whether there is a search result, and if there is, the article is displayed, and if not, "There is no corresponding post!" Is displayed.

This completes the implementation.

in conclusion

Since it is a part of the implementation, there may be some expressions that are difficult to understand, Please point out any questions.

Recommended Posts

[Rails 6] Implementation of search function
Implementation of search function
Rails search function implementation
Rails fuzzy search function implementation
Implementation of sequential search function
[Rails] Implementation of category function
[Rails] Implementation of tutorial function
[Rails] Implementation of like function
[Rails] Implementation of CSV import function
[Rails] Implementation of image preview function
[Rails] About implementation of like function
[Rails] Implementation of user withdrawal function
[Rails] Implementation of CSV export function
Rails hashtag search implementation
[Rails] Implement search function
Rails [For beginners] Implementation of comment function
[Rails 6] Implementation of SNS (Twitter) sharing function
Implementation of pagination function
Search function [copype implementation]
[Vue.js] Implementation of menu function Implementation version rails6
[Ruby on rails] Implementation of like function
[Vue.js] Implementation of menu function Vue.js introduction rails6
Implementation of Ruby on Rails login function (Session)
[Rails 6] Implementation of inquiry function using Action Mailer
[Rails] Implementation of image enlargement function using lightbox2
[Rails] Implementation of retweet function in SNS application
Implementation of search function Learning memo (portfolio creation)
[Rails] Implement User search function
Search function using [rails] ransack
Use ransack Search function implementation
Implementation of like function (Ajax)
Implementation of image preview function
Implementation of category pull-down function
Login function implementation with rails
[Rails 6] Pagination function implementation (kaminari)
Ruby on Rails <2021> Implementation of simple login function (form_with)
Implementation of Ruby on Rails login function (devise edition)
[Ruby on Rails] Implementation of tagging function/tag filtering function
[Rails] Implementation of multi-layer category function using ancestry "Preparation"
[Rails] Implementation of multi-layer category function using ancestry "seed"
[Rails] Implementation of SNS authentication (Twitter, Facebook, Google) function
[Rails] Set validation for the search function using Rakuten API (from the implementation of Rakuten API)
[Rails] Implementation of user logic deletion
Add a search function in Rails.
Kaminari --Added pagination function of Rails
[Rails] Implementation of many-to-many category functions
[Rails] gem ancestry category function implementation
[Ruby on Rails] Comment function implementation
[Rails 6] Like function (synchronous → asynchronous) implementation
[Rails] Comment function implementation procedure memo
Implementation of like function in Java
[Rails] Implementation of multi-layer category function using ancestry "Editing form"
[Rails] Implementation of multi-layer category function using ancestry "Creation form"
Rails sorting function implementation (displayed in order of number of like)
[Rails] Implementation of tagging function using intermediate table (without Gem)
[Rails] Implementation of new registration function in wizard format using devise
[Ruby on Rails] Search function (not selected)
[Rails] Addition of Ruby On Rails comment function
Implementation of user authentication function using devise (2)
DM function implementation
Let's create a TODO application in Java 6 Implementation of search function