Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails虚拟属性未验证_Ruby On Rails_Ruby_Validation_Virtual Attribute - Fatal编程技术网

Ruby on rails Rails虚拟属性未验证

Ruby on rails Rails虚拟属性未验证,ruby-on-rails,ruby,validation,virtual-attribute,Ruby On Rails,Ruby,Validation,Virtual Attribute,我猜在很多方面我还是一个新手,对rails的一些东西。 我有付款的ActiveRecord模型。 但是,它只有两件事情被添加到它的表中,并且一旦我们从authorize.net得到肯定的响应,这些事情就会被完成。 在这个模型的控制器中,我有我的购物车表单。 在购物车表单中,我有从@client提取的默认值的账单信息和信用卡信息。看起来有点像这样: <%= form_for @payment, :url => { action: "checkout" } do |f| %> ..

我猜在很多方面我还是一个新手,对rails的一些东西。 我有付款的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 %>

然而,到目前为止,表单将全部绕过此验证,并转到签出。任何帮助都将不胜感激!如何使这些验证正常工作?

如果您想深入了解技术细节,大多数Rails的内置验证程序都继承自ActiveModel::EachValidator,并且该验证程序通过“读取属性”从ActiveModel显式检查属性集合以进行验证。如果使用attr#u访问器设置了#zip和#cardname,则它们很可能不是#属性的一部分,因此验证程序会跳过它们

最简单的解决方法是编写一个验证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?)可能有些过分,但当逻辑变得更复杂和/或您可以重用逻辑时,这会很有帮助。

好吧,我添加了它,现在我得到了:ArgumentsError in Payments Control#cart您需要至少提供一个验证Orry,那个密码输入错误。验证行应该显示“validate”而不是“validates”(否)。修好了,这对我有用。我有一个rspec FactoryGirl构建传递,因为有效的方法是传递我的虚拟属性。添加自定义验证解决了这个问题。
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