When submitting billing information in the past I’ve always used
attr_accessor for credit card details as they should not be saved in
the database. In addition I always end up storing the card
expiration date so that the date form helper works correctly.
With Active Model it seems logical to create a CreditCard class to
hold this data instead.
1st issue.
It seems there still isn’t support for handling the form date_select.
(the card_expires_on(*) parameters). Should this work? Perhaps I’m
just missing an ActiveModel module
2nd issue.
In a perfect world this CreditCard class would be on the same form as
an ActiveRecord Order class but I have not been able to get an
ActiveModel to work as a nested object on a form.
something like this… on the order new form
<%= form_for @order do |f| -%>
. order stuff here…
<% f.fields_for :credit_card do |cc_fields| %>
<%= cc_fields.label :card_number, ‘*Number’ %>
<%= cc_fields.text_field :card_number, :class =>
‘text’, :autocomplete => ‘off’ %>
<% end %>
I have not found what magic I need to add to the order model to make
this work.
The <% f.fields_for :credit_card do |cc_fields| %> block is never
executed
if credit card was an ActiveRecord I would simply put
has_one :credit_card
accepts_nested_attributes_for :credit_card
instead I added a
attr_accessor :credit_card to the Order ActiveRecord class
and my credit_card class looks like this…
class CreditCard
include ActiveModel::Validations
include ActiveModel::AttributeMethods
include ActiveModel::Callbacks
include ActiveModel::Conversion
extend ActiveModel::Naming
# belongs_to :user
attr_accessor :card_type, :card_number, :card_verification,
:card_expires_on, :agree
validates :card_type, :card_number, :card_verification,
:card_expires_on, :agree, :presence
=> true
def initialize(attributes = {})
expire_date = {}
#raise attributes.inspect
attributes.each do |name, value|
send("#{name}=", value)
#this breaks on date items from date_select
end
end
def persisted?
false
end
end
Any idea what I am missing?