rails:3365
From: "jet.lfo" <jet.lfo@g...>
Date: Mon, 18 Jan 2010 10:35:49 +0900
Subject: [rails:3365] ActiveRecord で order を簡易的にする方法模索中
こんにちは。jet.lfo です。
みなさんはどのように解決しているのでしょうか?
良いテクニックとかプラグインがあれば教えてください。
以下、ぱっと思いつきで namede_scope あたりをうまく使えないかなー、と。
しかし、named_scope は :conditions オプション以外のパラメータはマージしてくれないようだ。
# :order オプションとかマージしてくれると楽だと思うんだけど。
#とりあえずの実行環境 ruby: 1.8.7(cygwin), Rails: 2.3.5, database: sqlite3
試しに直截的な named_scope での定義。
-----< 例1コード ここから >-----
named_scope :asc, lambda{ |column_name| { :order => "#{column_name} ASC"} }
named_scope :desc, lambda{ |column_name| { :order => "#{column_name} DESC"} }
-----< 例1コード ここまで >-----
-----< 例1実行結果 ここから >-----
HogeContent.asc(:id).desc(:name).asc(:status).find(:all)
#=> HogeContent Load (0.0ms) SELECT * FROM "hoge_contents" ORDER BY id ASC
-----< 例1実行結果 ここまで >-----
named_scope を多重にした場合の結果。先頭の :order だけ有効になる。
しかし、なんとなく named_scope が使えそうなのでぐりぐりしてたら、こんな形になった。
named_scope の引数で ActiveRecord::NamedScope::Scope にインスタンスメソッドの追加定義ができるようなので、
そこで小細工を入れてみた。
-----< 例2コード ここから >-----
named_scope :orders do
# proxy_options[:order] を編集する。
def add_order(column_name, ordering)
_orders = proxy_options[:order] ? proxy_options[:order].split(/,\s*/) : []
_orders << "#{column_name} #{ordering}"
proxy_options[:order] = _orders.join(", ")
self
end
# ASC の追加
def asc(column_name)
add_order(column_name, "ASC")
end
# DESCの追加
def desc(column_name)
add_order(column_name, "DESC")
end
end
-----< 例2コード ここまで >-----
-----< 例2実行結果 ここから >-----
HogeContent.orders.asc(:id).desc(:name).asc(:status).find(:all)
#=> HogeContent Load (0.0ms) SELECT * FROM "hoge_contents" ORDER BY id ASC, name DESC, status ASC
-----< 例2実行結果 ここまで >-----
・他の named_scope で :order オプションを弄ってはならない
・orders の直後に連続する asc/desc でなければならない
という仕様がもうダサイ・・・けれども、少し簡単になった気はする。気のせい?
lambda の中で proxy_options とか proxy_scope の値が取れれば幸せになれそうかなー。
以上、よろしくお願いします。
--
ML: rails@r...
使い方: http://QuickML.com/