実現したかったこと/実装例Dirtyの活用したサンプルコードおわりに参考はじめにはじめまして、スタメンでエンジニアをしているショウゴです。Railsを用いてバックエンドの開発を主に担当しています。カラムの値を変化させて、ステータスの変更・管理を行っているモデルに対して新たなバリデーションを実装する作業の中で、特定のカラムの変化を察知し、特定のステータス変化が発生する時にだけバリデーションを実行するように実装する必要がありました。そのため、特定のカラムの変更状況の確認と変更前後の値の取得を行うために、ActiveRecord::AttributeMethods::Dirtyモジュールを活用しました。ActiveRecord::AttributeMethods::DirtyとはDirtyは、オブジェクトに変更があった場合に検出ができ、変更前後の値を取得することができます。使用できるメソッドは下記の通りです。"fuga")とも書けます。"fuga")でも書けます。メソッド名の変遷Railsの旧バージョンでは、下記のメソッドが用意されていましたが、現在ではそれらは非推奨となり、より分かりやすい表現に変わっています。時制に注目することがポイントです。注)以下は現在非推奨です。ver.6.0.3.5において、検証用に下記のモデルを準備しました。DBのカラムに対するデフォルト値(以下、初期値)の設定の有無の影響を再現するため、初期値が無いnameカラムと初期値があるstatusカラムを用意しました。}endcreateとupdateの過程における挙動を確認した結果が下記になります。良いのではないかと当初は考えました。実装の過程で初期値がある場合と初期値が無い場合で、下記の様に少し挙動が異なることが分かりました。"inviting"初期値が無い場合は、nilから設定値に変化するのですが、初期値がある場合は、nilではなく初期値から設定値に変化するという挙動になることが分かりました。初期値がある場合にカラム名_change_to_be_savedを使うと設定値が初期値と同等の場合はnilが返り、設定値が初期値以外の場合は配列が返るため、nilの場合と配列の場合を判定仕分ける必要が出てきました。今回の実装で実現したかったことに対して実装した内容が下記の通りです。"ユーザー数が多すぎるため、ユーザーを新規登録できません。"ユーザー数が多すぎるため、ユーザーを更新できません。endバリデーションが必要か否かを判定するメソッドはcreateとupdateで共通としたい。新規作成する場合は、バリデーション対象としたい。メソッドを使わずにcreateのsave直前の値を確認したい。inviting→activeの更新はバリデーション対象から除外したい。endDirtyの活用したサンプルコード検証の結果を踏まえて、下記のサンプルコードのように実装することでバリデーション対象の状態変化か否かを判定できる様になりました。"ユーザー数が多すぎるため、ユーザーを新規登録できません。"ユーザー数が多すぎるため、ユーザーを更新できません。invitingのユーザーはカウント対象となる。endおわりに今回は、ActiveRecord::AttributeMethods::Dirtyモジュールの活用方法について紹介させていただきました。今回の紹介した内容が少しでも参考になれば幸いです。興味を持っていただいた方は、是非下記の募集ページを御覧ください。株式会社スタメンでは、エンジニア採用を強化しています。ご興味のある方はぜひエンジニア採用情報をご覧ください。引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。