Rails select2でajax処理を行い1万件以上でもスムーズに動くようにする。
jQueryのライブラリでいい感じに選択機能を実装するselect2があります。
今回はselect2でajax処理を行う方法を紹介します。
- 本家サイト
Select2 - The jQuery replacement for select boxes
本家サイトのExamplesにもあるようにselect2にajax処理でデータを取得し、一覧にして出す機能がもともとオプションとして存在しています。
viewはslimですが以下のように実装を行いました
f.collection_selectionはrails標準のhelperです。select2を当てるbook_searchをclassとして定義しています
multipleをtrueにすることで複数選択にしています。ここらへんはお好みで
= f.collection_select :book_ids, books, :id, :name, { include_blank: "" }, multiple: true, class: "form-control book_search"
Javascriptは本家サイトのExampleを参考に実装しました。
ajax処理を行い受け取ったobjのidとname を返しています。
$(".book_search").select2({ ajax: { url:'/books/search.json', dataType: 'json', delay: 50, data: function(params) { return { q: params.term }; }, processResults: function (data, params) { return { results: $.map(data, function(obj) { return { id: obj.id, text: obj.name }; }) }; } }, theme: "bootstrap", width: "100%", placeholder: "本選択", });
controller側は以下のようにしました。あくまで参考程度に
jsonで値を返すようにしています。
class BooksController < ApplicationController def book_search respond_to do |format| format.json { render json: @books = Books.search(params[:q]) } end end end class Books < ActiveRecord::Base scope :search, lambda { |query| where('name LIKE ?', "%#{query}%").limit(100) } end
これで1万件ほどのselect表示をajax処理で検索させることによってページのローディングはかなり改善されました。
データが1万件近くあるとselectのoptionに値をセットするのに時間がかかりviewの表示に20秒ほどかかっていました。。。。(遅すぎ)
ちょっと雑な書き方になりましたが、他に似たように実装したいと考えている人の参考になれば幸いです。
ちなみに自分は以下の記事を参考にさせていただきました。