2013-11-17 5 views
0

Я предполагаю, что во многих отношениях я все еще новичок с некоторыми из этих рельсов. У меня есть модель ActiveRecord для платежей. Но у него есть только две вещи, которые добавляются в ее таблицу, и это делается после того, как мы получим положительный ответ от authorize.net. В контроллере для этой модели у меня есть моя форма для корзины. В карточной форме у меня есть информация о выставлении счетов с значениями по умолчанию, полученными из @client и информацией о кредитной карте. Это выглядит как это:Rails Виртуальный атрибут (ы) Не проверяется

<%= 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 

Тем не менее, до сих пор форма будет обойти эту проверку все вместе и идет направление к кассе. Любая помощь будет принята с благодарностью! Как я получу эти проверки для правильной работы?

ответ

1

Если вы хотите ознакомиться с техническими сведениями, большинство проверенных валидаторами Rails наследуют от ActiveModel :: EveryValidator, и этот валидатор явно проверяет коллекцию атрибутов из ActiveModel с помощью #read_attribute_for_validation. Если #zip и #cardnumber были настроены с помощью attr_accessor, они, скорее всего, не часть # атрибутов и, таким образом, пропущена валидатором.

Простейшим обходным решением было бы написать частный метод, который проверяет размер zip/cardnumber и затем вызывает .validates с именем этого метода проверки. Образец, который был рекомендован Коз будет выглядеть следующим образом ...

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?) Может быть излишним в данном конкретном случае, но это полезно, когда логика становится все более сложной и/или вы можете повторно использовать логику.

+0

Ну, я добавил его, и я получаю это сейчас: ArgumentError in PaymentsController # cart Вам необходимо предоставить хотя бы одну проверку. –

+0

К сожалению, опечатка в этом коде. В строке валидации должно быть указано «validate» вместо «validates» (нет s). Исправлена. – AndyV

+0

Это сработало для меня. У меня была передача rspec FactoryGirl, поскольку действительный метод передавал мои виртуальные атрибуты. Добавление пользовательской проверки разрешило ее. – Tim