[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]