-1

私はレールでのカスタム検証の学習に取り組んでおり、2 つのフォーム フィールドを比較する目的でそれを適用しようとしています。これまでのところ、保存したカスタム my カスタム バリデーターに 1 つの値を簡単に渡すことができ、app/validation/pin_validator.rb正常に動作します。しかし、フォームから2つのデータを受け入れる次のようなものを設定したいと思います:

class PinValidator < ActiveModel::EachValidator
  def validate_each (record, attribute, value)
    if value1 > value2
      record.errors[attribute] << (options[:message] || "validator working")
    end
  end
end

そして、モデルから次のように呼び出します。

validates :pin_number, :id_string, pin: true

:id_string:pin_numberはどちらもフォーム フィールドであり、 と として比較されますvalue1value2

これを行う方法はありますか?

よろしくお願いします!

注:上記の値の比較は、実際にはフロントエンドで少し JavaScript を使用して解決できます。サーバー側のソリューションを求めている理由は、最終的には両方の値をデータベース内の一連のエントリと比較するつもりだからです。上記の例は、私の質問を簡単なものに要約するためのものです。

4

2 に答える 2

1

Rails 側で検証を行うのではなくonClick、適切な制御ができると思われる値やその他のアクションを検証する JS アプローチを検討することもできます。

必要なのは、一意に名前が付けられた各フォーム フィールドから値を取得し、各フィールドの を比較して送信を許可/拒否するonClick単純な方法だけです。val()

フォーム フィールドを DB に保存されている値と比較する必要がある場合<input type="hidden>は、ページの読み込み時にその値を使用および保存して、上記と同じ方法で比較を行うことができます。

于 2014-12-09T21:49:04.080 に答える
1

ここのイニシャライザコードから推測できるよう@attributesに、メソッド内でリストされている属性にアクセスできるはずですvalidate_each

したがって、検証の定義で使用される属性名の配列であるrecord値を使用して、属性にアクセスできます。次のようにアクセスできます@attributes[:pin_number, :id_string]

def validate_each(record, attribute, value)
   value1 = record[@attributes[0]] # :pin_number
   value2 = record[@attributes[1]] # :id_string
   # the rest of the logic here
end

validate_eachこのメソッドは、検証定義にリストされている各フィールドに対して実行されることになっているため、2 回実行されることに気付きました。これにより、エラーが 2 回挿入されるなどの問題が発生する可能性があります。検証が実行されるたびにバリデーターインスタンスが作成されるかどうかを調査しています。そうであれば、フラグを設定することでこの二重検証を回避できます。たとえば@already_run、そのフラグが 2 回目に true であった場合に戻ります。バリデーターの新しいインスタンスは、次に何かを検証する必要があるときに作成されるため、フラグは他に影響を与えません。

于 2014-12-09T22:24:03.970 に答える