Ransack
Rails 내에서 search form을 손쉽게 만들기 위해서 사용되는 젬인 ransack 에 대해서 알아보고자 한다.
주로 admin 페이지에서 활용하기 위함으로 사용되며, 손쉽게 search form을 커스텀할 수 있다.
(참고 ransack의 성능에 대한 이야기, 요약하자면 abstraction layer로서, ransack 자체가 DB 조회에 대한 성능을 좌우하진 않음)
아래와 같은 페이지를 만드는게 목적이다.
아래 이미지의 좌측에 존재하는 저러한 검색 form을 만들어서 조금 더 손쉽게 검색을 할 수 있도록 하고자 하는데 rails 내에서는 ransack gem을 통해서 손쉽게 만들 수 있다.
프로젝트 사전 준비
준비물
추가로 해볼 수 있는 것들(꾸미기)
- will_paginate-bootstrap4 – 페이지네이션 부트스트랩 라이브러리
- bootstrap – 가장 유명한 반응형 프론트엔드 프레임워크
먼저 빠르게 프로젝트를 만들기.
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
github.com/activerecord-hackery/ransack
'Web Programming > Ruby on Rails' 카테고리의 다른 글
Rails API 만들기 (feat. Postman 사용) (2) | 2021.04.04 |
---|---|
Rails Test (feat. TDD를 위한 기반) (2) | 2021.03.28 |
Rails Database 관리 Gem(rails_db) (0) | 2021.03.20 |
Rake db 명령어(feat. schema:load vs migrate) (5) | 2021.03.14 |
Rbenv Ruby 환경관리 및 설치 (0) | 2021.03.14 |