본문 바로가기

Web Programming/Ruby on Rails

Rails 손쉬운 검색 form ransack

Ransack

 

Rails 내에서 search form을 손쉽게 만들기 위해서 사용되는 젬인 ransack 에 대해서 알아보고자 한다.

주로 admin 페이지에서 활용하기 위함으로 사용되며, 손쉽게 search form을 커스텀할 수 있다.

(참고 ransack의 성능에 대한 이야기, 요약하자면 abstraction layer로서, ransack 자체가 DB 조회에 대한 성능을 좌우하진 않음)

 

아래와 같은 페이지를 만드는게 목적이다.

 

아래 이미지의 좌측에 존재하는 저러한 검색 form을 만들어서 조금 더 손쉽게 검색을 할 수 있도록 하고자 하는데 rails 내에서는 ransack gem을 통해서 손쉽게 만들 수 있다. 

 


프로젝트 사전 준비

 

준비물

  • rails 프로젝트
  • faker – fake 데이터를 만들어주는 젬
  • ransack – 오늘의 주인공... 오브젝트 기반의 서치 라이브러리

추가로 해볼 수 있는 것들(꾸미기)

 

먼저 빠르게 프로젝트를 만들기. 

rails new sample

 

그리고 아래의 준비물들인 젬을 Gemfile.rb에 추가한다.

1
2
3
4
5
# Gemfile
  gem 'faker'
  gem 'bootstrap''~> 4.3.1'
  gem 'ransack'
  gem 'will_paginate-bootstrap4'
cs

(당연히 bundle install 필수)

 

그리고 Scaffolding을 활용해 CRUD 를 만들고 스키마를 만들었으니 migrate 실행.

rails generate scaffold book isbn:bigint name author year:integer price:decimal{7-2} status:boolean genre:integer
rake db:migrate

 

그리고 편의를 위해서(굳이 안해도 되고 수작업으로 해도 되긴 하지만...) fake 젬을 활용해서 seeds에다가 데이터를 추가해둔다.

1
2
3
4
5
6
7
8
9
10
11
12
13
# db/seeds.rb
100.times do
  Book.create(
    isbn: Faker::Code.isbn,
    name: Faker::Book.title,
    author: Faker::Book.author,
   year: Faker::Number.between(from:1900, to:2019),
   genre: Faker::Number.between(from:1, to:5),
    price: Faker::Commerce.price,
    status: Faker::Boolean.boolean
  )
end
 
cs

(seeds가 낯설다면 seeds에 대해서는 해당 링크를 참조)

그리고 명령어를 실행한다. 

rake db:seed

 

콘솔을 통해 확인해보면 아래와 같이 100개의 fake 데이터가 생성됨을 확인할 수 있다.

 

사전 준비의 마지막으로 Book 모델의 장르 컬럼에 대해서 enum(열거형) 자료형을 통해서 우리가 값을 지정해주도록 하자.

1
2
3
# app/models/book.rb
enum genre: { fantasy: 1, romance: 2, horror: 3, fiction: 4, poetry: 5 }
 
cs

 

 아래와 같이 정상적으로 만들어진 것을 확인할 수 있다.

(나의 경우 node 버전이 낮아서 이슈가 있었는데 'nvm install 10' 을 통해서 10.x 의 최신 버전을 설치하고 'nvm use 10' 을 했다)

밑에 엄청난 양의 글들이 있다.

 

(옵션) 추가적으로 부트스트랩 사용을 위해 application.css 파일을 scss 확장자로 변경하고 아래의 한줄을 추가해준다.

 mv app/assets/stylesheets/application.css app/assets/stylesheets/application.scss
/* app/assets/stylesheets/application.scss */
@import "bootstrap";

먼저, ransack을 사용하기 위해서는 app/controllers/books_controller의 index 함수를 아래와 같이 변경해줘야 한다.

단순히 Book에서 데이터를 가져오는 것이 아닌 ransack을 통해서 넘어오는 파라미터(q)에 맞게 검색결과를 제공해주기 위해서다.

1
2
3
4
5
  def index
    # @books = Book.all
    @q = Book.ransack(params[:q])
    @books = @q.result
  end
cs

 

그리고 app/views/books/ndex.html.erb 파일도 이에 맞게 수정해준다.

<p id="notice"><%= notice %></p>

<h1>Books</h1>

<%= search_form_for @q do |f| %>
  <%= f.label :name %>
  <%= f.text_field :name_cont, class: 'form-control' %>
  <%= f.submit class: 'btn btn-primary' %>
<% end %>

<table>
  ...

 

그럼 1차적으로 아래와 같이  name 으로 검색할 수 있는 페이지가 완성된다(실제로 동작도 잘 된다).

이런식으로 다른 컬럼들도 추가해줄 수 있다.

추가 시 검색 조건들은 공식 깃헙을 참조하면 된다.

 

<p id="notice"><%= notice %></p>

<h1> 📓Books</h1>


<%= search_form_for @q do |f| %>
  <div class="form-group" style="width: 20vw; padding:1vw;">
    <%= f.label :isbn %>
    <%= f.text_field :isbn_eq, class: 'form-control' %>
    <%= f.label :name %>
    <%= f.text_field :name_cont, class: 'form-control' %>
    <%= f.label :author %>
    <%= f.text_field :author_cont, class: 'form-control' %>
    <%= f.label :year %>
    <%= f.text_field :year_eq, class: 'form-control' %>
    <%= f.label :price, "Price" %>
    <%= f.text_field :price_gteq, class: 'form-control' %>
    <%= f.text_field :price_lteq, class: 'form-control' %>
    <%= f.label :genre %>
    <%= f.select(:genre_eq, options_for_select(Book.genres.map {|k, v| [k.humanize.capitalize, v]}, f.object.genre_eq), { include_blank: true }, {class: "form-control" }) %>
    <%= f.submit class: 'btn btn-primary' %>
  </div>
<% end %>

<table style="width: 70vw; padding:2vw;">
  ...

그 결과 아래와 같이 페이지가 잘 나오며 검색도 잘 된다.

프론트엔드와 페이지네이션은 다음 기회에...

 


참고

 

blog.magmalabs.io/2019/03/12/searching-with-ransack-in-ruby-on-rails.html

 

Searching with Ransack in Ruby on Rails - MagmaLabs Technical Blog

Reading Time: 6 minutes Share via: Sometimes we need or we want to develop a module quickly and easily that includes filters, sorting, pagination and we don’t want to spend so much time on it, that’s why there are already some implemented and tested to

blog.magmalabs.io

github.com/activerecord-hackery/ransack

 

activerecord-hackery/ransack

Object-based searching. . Contribute to activerecord-hackery/ransack development by creating an account on GitHub.

github.com