最近は、自分用にRailsの挙動を拡張するために書いた
lib/xxxx_ext.rb
が増えてきました。
こういったファイルはconfig/initializer/
の直下に
置いても良いのですが、ON/OFFを切り替えやすいので、
config/initializer/libs.rb
の中から、require "xxxx_ext"
を呼ぶようにしています。
さて、今回はActiveRecordをさらに便利に使うために、
僕が行っている拡張を紹介します。
lib/active_record_ext.rb
1 module ActiveRecord
2 class Base
3 def self.[](arg, *args)
4 case arg
5 when Range
6 find arg.to_a
7 when Hash
8 find :all, arg
9 when :first, :all
10 find arg, *args
11 when :last
12 find(:all, *args).last
13 when Symbol
14 send "find_#{arg}", *args
15 else
16 find arg, *args
17 end
18 end
19
20 def update_counters(counters)
21 self.class.update_counters id, counters
22 end
23 end
24 end
どうでしょう、お分かりだと思いますが、ARクラスに
インデクサ (rb_aref) を定義しています。こんな感じに動作します。
1 >> Site[1].uri
2 => "http://www.google.com/"
3 >> Site[1,2].map &:uri
4 => ["http://www.google.com/", "http://www.wikipedia.org/"]
5 >> Site[1..2].map &:uri
6 => ["http://www.google.com/", "http://www.wikipedia.org/"]
7 >> Site[:last].title
8 => "Ruby/Tk チュートリアル"
9 >> Site[:by_uri, "http://www.google.com/"].uri
10 => "http://www.google.com/"
実際のアプリケーションコードの中ではあまり使っていないですが、
script/console
の中で使うのには大変便利です。
最後に、update_counters
は、インスタンスメソッドとして
欲しかったので追加しています。
Rails 2.0から仕様が変わった counter_cache
については、
日比さんがこちらに記事
「既存のモデル/テーブルでcounter_cacheを使う:update_counters」
を書いているので参照してみてください。