やる気がストロングZERO

やる気のストロングスタイル

【Rails】Active Record のコールバックは使わない方がいいと思った

Active Recordのコールバックは便利な事もあるのかもしれないが、注意して使わないとコードの可読性がものすごく落ちていくので使わない方がいいと思った。

Active Record コールバック - Rails ガイド

コードリーディングで処理を追うのが難しくなる

コールバック処理は、ソースコード上で処理の連続性のないところに記述するので、その処理が実行されることが見逃されやすい。

例えば、以下のようなコードがある。
※コールバックに関する問題について以外は無視する(データが冗長だとか)

user = User.new()
user.fullname = "Taro Yamada"
user.save!

このコードを見たときに「users.fullnameカラムに"Taro Yamada"が保存された」と理解すると思う。

ところが、実際にDBに保存されたのは以下。

# usersテーブル
id: 1
fullname: "Taro Yamada"
firstname: "Taro"
lastname: "Yamada"

保存した覚えのないfirstnameとlastnameが保存されている。

改めて探してみるとUserモデルに以下の記述があった。
見逃していた。

User.rb

before_save :set_firstname_and_lastname

def set_firstname_and_lastname
    name = self.fullname.split(" ")
    self.firstname = name[0]
    self.lastname = name[1]
end

見逃してしまったのは、連続性の無いコードだったから。 これが以下の様に書いていたら見逃さなかったはず。

user = User.new()
user.fullname = "Taro Yamada"
user.firstname = user.fullname.split(" ")[0]
user.lastname = user.fullname.split(" ")[1]
user.save!

以降、コードリーディング時にはすべてのコードで「コールバックで何か処理されているかも」って探しながらコードをよまないといけない。
結構つらい。

※上記くらいの規模ならそれほど問題ないのかもしれないが、コールバック中心でビジネスロジックが構築されたりすると本当につらい。

なので、Active Recordのコールバックは使わないほうがいいと思った。

ActiveRecordが非常に薄くてコードが見渡しやすい状態をキープできるならありかも?

コールバックが補助的な処理しかしてなくて、かつ、ActiveRecordのコードが非常にシンプルであるならコールバックを使っても問題にならないのかもしれない。

ただし、複数人で開発などしているとなかなか制御の徹底など難しい場合もあるので最初から使わないようにするのが良いのではないかと思った。