【RubyOnRails】after_initializeとFactoryBot
//
ActiveRecordのコールバック
まずは下のサイトさんをご覧ください。
# Hoge.create()の実行順 hoge = Hoge.new(name: "hoge") #initialize after_initialize #newメソッドで生成したときのみ hoge.save! #BEGIN TRANSACTION before_validation #validation after_validation #ROLLBACK after_rollback #validationに失敗した時のみ before_save around_save before_create around_create #INSERT INTO "hoges" after_create after_save # COMMIT after_commit # 引用元:https://qiita.com/rtoya/items/29cef3e328299781a328
(引用元ではafter_initialize
はnew
の時のみとありますが、インスタンスが生成されるたびに呼ばれるので、Hoge.create
やHoge.first
等を使用した場合も呼ばれるはずです。)
で今回after_initialize
で呼ばれるメソッドをテストしたかったというお話です。
そもそも
上に書いたように、new
で呼ぶ以外にもafter_initialize
を走らせる方法はたくさんあるので、基本的にモデルのコールバックテストをするのには困らないはずです。
ですが、私はFactoryBot.new(:hoge)を呼ぶと同時にafter_initialize
を見ようとしたためハマりました。
FactoryBot.create(:hoge)と、Hoge.create()
てっきり同じように呼ばれるのかと思いきや、若干違うようです。
create
の引数に初期値を渡してインスタンスを生成する場合、FactoryBot
の方はafter_initialize
時に初期値がまだ反映されません。
つまり..
本家のHoge.create(name: "hoge")
#initialize after_initialize # すでにself.name に"hoge"が入っている hoge.save! #BEGIN TRANSACTION before_validation #validation after_validation
FactoryBot.create(:hoge,name:"hoge")
#initialize after_initialize # まだselfは全てnil hoge.save! #BEGIN TRANSACTION before_validation # self.nameに"hoge"が入っている。 #validation after_validation
という感じになります。
余談
factorybot
の値を使うのであれば、
Hoge.create(FactoryBot.attributes_for(:hoge))
とかどうでしょう?
よく理解できていないので、何かあれば教えてください。