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/