Oasist Blog

This blog features Linguistics, Engineering&Programming and Life Career.

Ransack Search Form

f:id:oasist:20200614004721p:plain
Ruby on Rails

Contents

1. Environment

2. Requirements

Users can search for events with

  • name: contained
  • place: contained
  • content: contained
  • start_at: later than or equal to
  • end_at: earlier than or equal to

3. Gemfile

Add ransack in Gemfile and run docker-compose exec app bin/rails bundle.

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.7.2'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.3', '>= 6.0.3.2'
...

# SearchForm
gem 'ransack', '~> 2.3.2'

4. Controllers

Get params[:q] value sent from views with ransack class method, call the result with result instance method and assign events to the instance variable @events in controllers.

def index
  @q = Event.ransack(params[:q])
  @events = @q.result.page(params[:page]).per(paginate_per).default
end

5. Views

Ransack provides the following {attr}_{options} helper methods that can be used in views.

Option Meaning Symbol
*_eq equal ==
*_noteq not equal !=
*_lt less than <
*_lteq less than or equal <=
*_gt grater than >
*_gteq grater than or equal >=
*_cont contains value

Apply appropriate options to each attributes and implement the search form with form_with helper method.

<div class="panel panel-default panel-search">
  <div class="panel-body">
    <%= search_form_for(@q, class: 'mb-5') do |f| %>
      <div class="row form-group">
        <div class="col-sm-6">
          <%= f.label :name_cont, Event.human_attribute_name(:name), class: 'control-label col-sm-5 nowrap' %>
          <div class="col-sm-11 col-md-9">
            <%= f.search_field :name_cont, class: 'form-control' %>
          </div>
        </div>
        <div class="col-sm-6">
          <%= f.label :place_cont, Event.human_attribute_name(:place), class: 'control-label col-sm-5 nowrap' %>
          <div class="col-sm-11 col-md-9">
            <%= f.search_field :place_cont, class: 'form-control' %>
          </div>
        </div>
      </div>
      <div class="row form-group">
        <div class="col-sm-12">
          <%= f.label :content_cont, Event.human_attribute_name(:content), class: 'control-label col-sm-5 nowrap' %>
          <div class="col-sm-11 col-md-10">
            <%= f.search_field :content_cont, class: 'form-control' %>
          </div>
        </div>
      </div>
      <div class="row form-group">
        <div class="col-sm-6">
          <%= f.label :start_at_gteq, Event.human_attribute_name(:start_at), class: 'control-label col-sm-5 nowrap' %>
          <div class="col-sm-11 col-md-9">
            <%= f.datetime_field :start_at_gteq, class: 'form-control' %>
          </div>
        </div>
        <div class="col-sm-6">
          <%= f.label :end_at_lteq, Event.human_attribute_name(:end_at), class: 'control-label col-sm-5 nowrap' %>
          <div class="col-sm-11 col-md-9">
            <%= f.datetime_field :end_at_lteq, class: 'form-control' %>
          </div>
        </div>
      </div>
      <div class="form-btn-field">
        <%= f.submit class: 'btn btn-primary' %>
      </div>
    <% end %>
  </div>
</div>

6. Assets

Define styles for the search form in /app/assets/stylesheets/ransack.scss.

.panel {
  margin-top: 20px;
  margin-bottom: 20px;
  background-color: #fff;
  border: 1px solid transparent;
  border-radius: 4px;
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
  &-default {
    border-color: #ddd;
  }
  &-body {
    padding: 15px;
  }
}

.form-btn-field {
  margin-top: 20px;
  text-align: center;
}

8. Deliverables

f:id:oasist:20201123125400p:plain
Ransack Search Form