LoginSignup
0
0

More than 1 year has passed since last update.

【Rails】カスタムバリデーションを作成してAncestyに階層制限をかける

Posted at

はじめに

現在、共同開発にてドキュメント作成アプリを開発中です。
その中でAncestryを用いた階層構造を実装しており、機能としてはドキュメント作成時にタイトル部分に/ を入力して、文章を区切ることによりディレクトリが作成できるようになっています。

今回はディレクトリの階層を5階層までにしたかったので、バリデーションをかけようと思います。しかし、デフォルトのバリデーションオプションでは難しそうでした。

そこで色々調べていくとActiveModel::EachValidator を使うことで、独自のバリデーションを追加することが分かり便利だなと思ったため、備忘録として使い方を残しておきます。

カスタムバリデーターの作成

カスタムバリデーターとは

ActiveModel::ValidatorActiveModel::EachValidator を使って自作のバリデーションを作成することです。

独自のバリデーションルールを追加しようとする時に、modelに書くと可読性が悪くなり、更には管理も大変になってしまいます。それを防ぐためにバリデートクラスと呼ばれる、バリデーションを自作するためのクラスを継承したクラスを作ります。

今回は使いやすいということで、ActiveModel::EachValidator を継承したクラスを作成して、そこに独自のバリデーションルールを書いていきます。

ファイルの作成

  1. app/配下にvalidatorsディレクトリを作成します。
  2. app/validators/<検証名>validator.rbの形式でファイルを作成
  3. ActiveModel::EachValidator を継承したクラスを作成
app/validators/ancestry_validator.rb
class AncestryValidator < ActiveModel::EachValidator
end

ここで指定したクラス名が、modelでカスタムバリデーターを呼び出す際に使われます。

これでカスタムバリデーションを実装する準備ができたため、後はこのファイルにロジックを書いてあげれば完了です。

バリデーションルール作成

まずはカスタムバリデーション用にRailsが用意してくれている、validate_eachメソッドを追加しましょう。

app/validators/ancestry_validator.rb
class AncestryValidator < ActiveModel::EachValidator
    def validate_each(record, attribute, value)
    end
end

validate_each メソッドの3つの引数

validate_each メソッドの3つの引数の中身にはそれぞれ、以下の値が入ります。

record

ここにはオブジェクトが入ります。

attribute

これには属性が入ります。
今回で言えば:ancestyが返ってきます。

value

ユーザーが入力した値が入ります。
文字数検証などに使います。

以上のことを踏まえた上で、カスタムバリデーションを設定していきましょう!

カスタムバリデーション設定

今回は5階層以降のディレクトリを作成したくないため、以下のように設定しました。

class AncestryValidator < ActiveModel::EachValidator
    def validate_each(record, attribute, value)
        if value.count("/") > 3
      record.errors.add(attribute, "ディレクトリは6つ以上作成できません!")
    end
    end
end

/ の数により何階層目かを判断して、3つ以上になると6階層目になるためバリデーションに引っかかるようにしています。

  • record.errors.add(属性, メッセージ)

上記のようにすることでバリデーションを発生させて、メッセージを追加することができます。

属性を指定することで、今回なら「ancestryディレクトリは6つ以上作成できません!」と表示されるようになります。

呼び出し

最後に設定したバリデーションを使えるように、対象のモデルでカスタムバリデーションを呼び出す記述を追加しましょう!

validates :ancestry, ancestry: true

この記述により、ancestryカラムに対してAncestryValidatorクラスのカスタムバリデーションを適応させることができます。

まとめ

今回はActiveModel::EachValidator を使った、独自のバリデーションを作成する方法について紹介しました。

初めて自作のバリデーションを作成しましたが、これを使いこなせるようになれば何でも検証できて便利だなと思ったので、ぜひ使いこなせるようになりたいと思います!

0
0
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
0
0