我想在很多方面我仍然是一个新手,有一些这种铁轨的东西。 我有ActiveRecord付款模型。 但是,它只有两个东西被添加到它的表中,一旦我们从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和其他卡片信息字段。
我没有任何getter或setter方法(也许这就是我所缺少的)。
但是,我确实在付款模式中有这个:
validates :zip, presence: true, numericality: true
validates :cardnumber, presence: true, numericality: true
然而,到目前为止,表单将一起绕过此验证,并指向结帐。任何帮助将不胜感激!如何使这些验证正常工作?
答案 0 :(得分:1)
如果您想了解技术细节,大多数Rails的烘焙验证器都继承自ActiveModel :: EachValidator,并且此验证器通过#read_attribute_for_validation显式检查ActiveModel中的属性集合。如果使用attr_accessor设置了#zip和#cardnumber,则很可能不是 #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
在这种特殊情况下,将验证分成两个方法(assure_zip_not_blank和zip_blank?)可能有点过头了,但是当逻辑变得更复杂和/或你可以重用逻辑时它会很有用。