8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ActiveRecordのinitialize飛ばし

Posted at

ActiveRecordを使っていたところ、意外な挙動をすることがありましたが、実はRubyの標準機能で実現できることでした。

initialize…されない!?

ActiveRecordにある処理を組む過程で、(素直にafter_initializeを使えばいいものを)何を思ったかinitializeのオーバーライドを行って実装する…というように書いてしまったのですが、そのinitialize内の処理が、ときどきしか実行されないということに気づきました。

調べてみると、ActiveRecordを本当にnewする際にはinitializeが呼ばれるのですが、ActiveRecord::Relationから実体化するなど、DBから引いてきたときにはinitialize走らないとのことでした。

Ruby標準で作れる、未初期化オブジェクト

では、一体どんな手法を使えばinitializeしないオブジェクトを作れるのだろうと調べてみたら、じつは標準ライブラリにClass#allocateというのがあって、これを使うとまさに「特定のクラスだけど、inializeしていないオブジェクト」を作れるということでした。

ActiveRecordの場合は、「どうせすぐにデータを詰めるのだから、initializeは無駄」という最適化なのでしょうが、なかなか使う機会の少ない機能かなという気もしています。

#余談
initializeをオーバーライドする際に、引数は直接superに投げるだけで、オーバーライドした中では使わない、というような状況の場合、変数名を省略することもできます。

def initialize(*)
  #元の引数、ブロックはそのままsuperへ
  super
 
  #引数を使わない拡張処理
end
8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?