概要
一覧のソート
詳細
一覧のソート機能を実装します。
サンプル
仕様
テーブル構造の一覧のヘッダーにあるリンクをクリックすると
昇順降順を切り替えてソートする。
アイコンはKickstartを使用。
単一項目によるソートのみ対応。
page.js.coffee
Coffee Scriptの共通処理としてソート用のメソッドを追加。
submit直前にhiddenにソート対象のカラムと昇順降順を指定しています。
この処理は後ほど作成するソートリンクから呼び出します。
class @Page # other logic @sort_submit: (sort, order, form) -> document.getElementById('sort').value = sort document.getElementById('order').value = @next_order order form.submit() @next_order: (order) -> return "asc" if order is "desc" return "desc" if order is "asc" return "asc" if order is "none"
views/user/list.html.haml
一覧のフォームの中にhiddenでsortとorderを追加します。
テーブルヘッダーに、ソートリンクを設定するヘルパーを指定します。
ヘルパーの詳細はapplication_helper参照
※抜粋
=hidden_field_tag :sort, @sort =hidden_field_tag :order, @order / その他の処理 = content_tag :th, :id => "id" do = link_to_sort "/user/search", "user", "id", @sort, @order = content_tag :th, :id => "login" do = link_to_sort "/user/search", "user", "login", @sort, @order
controllers/user/user_controller.rb
user_controllerが単数形なのは命名間違えただけなのでスルー希望・・・。
画面初期表示のアクション時はソート指定無しで固定にするため、sort・orderにnoneを設定。
ソートリンクからはsearchアクションを呼び出す想定。
sortアクションで実際にソートを指定しています。
ActiveRecord::Baseをオープンして処理を追加したので実処理は
config/initializers/active_record.rbを参照
※抜粋
def index(user, notice, sort, order) @users = User.all @user ||= User.new @notice = notice @sort = "none" @order = "none" layout_settings main_menu: true, user_menu: true end def search(user, sort, order) @sort = sort @order = order set_user_input user search_user user, @sort, @order layout_settings main_menu: true, user_menu: true render :action => 'index' end private def search_user(user, sort, order) @users ||= User.login_is(user[:login]) .name_is(user[:name]) .email_is(user[:email]) .admin_is(user[:admin]) .deleted_is(user[:deleted]).order_by(sort, order)
models/user/users.rb
scopeとしてソートを定義。実処理はActiveRecord::Baseをオープンしてメソッドを追加しています。
class User < ActiveRecord::Base scope :order_by, order_by # other logic end
conf/initializer/active_record.rb
module ActiveRecord class Base class << self # other logic def order_by() lambda {|sort, order| next if sort == "none" || order == "none" order("#{sort} #{order}") } end end end end
application_helper.rb
def link_to_sort(url, model, column, sort, order) # taraは自作のヘルパーで、実際はt('activerecord.attributes.model.column')を呼び出しているだけです label = tara(model, column) link_to url, :onclick => "Page.sort_submit('#{column}', '#{order}', $(this).closest('form'))", method: :post do "<i class=\"icon-#{order_style(order.to_s, sort, column)}\">#{label}</i>".html_safe end end