I followed the railscast on activemerchant and have this code:
def validate_card
unless credit_card.valid?
credit_card.errors.full_messages.each do |message|
errors.add_to_base message
end
end
end
But t开发者_如何学Pythonhat doesn't wrap the field in a fieldWithErrors
div. So I tried:
def validate_card
unless credit_card.valid?
credit_card.errors.each do |error|
errors.add error
end
end
end
That still didn't work. I've read http://api.rubyonrails.org/classes/ActiveResource/Errors.html and http://activemerchant.rubyforge.org/ but I'm not reading them right or something.
Adding it to the list of errors and showing that error(s) later are two different things.
The first way you've got it looks right. That puts the error into the list of errors for this object (there might be other validation errors, for instance.)
Then, you can use error_messages_for()
(api ref) to output that error in your view. It's customizable for whatever you want to call your divs.
Or, you can do your own output by looping through @object.errors yourself.
I had a problem with this as well. My solution was twofold:
- Add a general 'Credit card is invalid' error to base
- Map each credit card error to my own model's attributes.
It ended up looking something like this:
def valid_credit_card
unless credit_card.valid?
errors.add(:base, 'Credit card is invalid') # optional
credit_card.errors.each do |attr, messages|
# Map to the model properties, assuming you used the
# setup from the Railscast
if attr =~ /month|year/
attr = 'card_expires_on'
elsif attr =~ /(first|last)_name/
# attr = attr
else
attr = "card_#{attr}".gsub(/_value/, '')
end
messages.each { |m| errors.add(attr, m) unless errors[attr].include?(m) }
end
end
end
This puts the errors on the proper attributes, which is especially helpful if you're using gems like simple_form or formtastic where the errors are output with their fields, and it adds the extra error on base in case for some reason the mappings don't work.
精彩评论