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