0

多くの点で、私はまだこのレール関連の初心者だと思います。支払い用の ActiveRecord モデルがあります。ただし、テーブルに追加されるのは 2 つだけで、authorize.net から肯定的な応答が返ってきたら、それらは完了します。このモデルのコントローラーには、カート フォームがあります。カート フォーム内には、@client から取得したデフォルト値とクレジット カード情報を含む請求情報があります。次のようになります。

<%= form_for @payment, :url => { action: "checkout" } do |f| %>
...show errors ...
<%= f.fields_for @client do |ff| %>
    <%= ff.label :firstname, 'First Name*' %>
    <%= ff.text_field :firstname %>
    ...more fields ....
    <%= ff.label :zip, 'Zip*' %>
    <%= ff.text_field :zip %>
<% end %>
<%= f.label :cardnumber, 'Card Number*' %>
<%= f.text_field :cardnumber %>
... more cc info fields ...
<% end %>

モデルに attr_accessor :cardnumber とその他のカード情報フィールドを追加しました。

これらのゲッターまたはセッターメソッドはありません(おそらくそれが欠けています)。

ただし、支払いモデルにはこれがあります。

validates :zip, presence: true, numericality: true
validates :cardnumber, presence: true, numericality: true

それでも、これまでのところ、フォームはこの検証をすべてバイパスし、チェックアウトに向かいます。どんな助けでも大歓迎です!これらの検証を適切に機能させるにはどうすればよいですか?

4

1 に答える 1

1

技術的な詳細を知りたい場合、Rails に組み込まれているほとんどのバリデーターは ActiveModel::EachValidator を継承しており、このバリデーターは #read_attribute_for_validation を介して ActiveModel からの属性コレクションを明示的にチェックします。#zip と #cardnumber が attr_accessor で設定されている場合、それらはおそらく#attributes の一部ではないため、バリデーターによってスキップされます。

最も簡単な回避策は、zip/cardnumber を検証するプライベート メソッドを記述し、その検証メソッドの名前で .validates を呼び出すことです。Kozが推奨するパターンは次のようになります...

class Payment
  attr_accessor :zip

  validate :assure_zip_not_blank

  private
    def assure_zip_not_blank
      errors.add(:zip, 'cannot be blank') if zip_blank? && new_record?
    end

    def zip_blank?
      self.zip.blank?
    end
end

検証を 2 つのメソッド (assure_zip_not_blank と zip_blank?) に分けるのは、この特定のケースではやり過ぎかもしれませんが、ロジックがより複雑になったり、ロジックを再利用できる場合に役立ちます。

于 2013-11-18T00:52:45.417 に答える