Rails 3 / ActiveModel for Credit Card information?

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?

Figured out why my ActiveModel was not displaying…

<% f.fields_for :credit_card do |cc_fields| %>

needs to be

<%= f.fields_for :credit_card do |cc_fields| %>

I have another nested element on this page that is an ActiveRecord.
That one gives a deprecation warning. For some reason the fields_for
that takes an ActiveModel gives no warning. It just doesn’t work.
odd.

Anyone know a built in way to handle date_select parameters from
ActiveModel?

just FYI… here is part of my view. (addresses is an ActiveRecord
and credit_card is an ActiveModel)

    <% f.fields_for :credit_card do |cc_fields| %>
      <%= render :partial => "cc_fields", :locals => { :cc_fields

=> cc_fields} %>
<% end %>
<% f.fields_for :addresses do |address_fields| %>
<%= render :partial => “address_fields”, :locals =>
{ :address_fields => address_fields, :use_org => true } %>
<% end %>

It doesn’t matter what order these are in the address form will always
display and the credit_card will not (unless i use <%=)

Have you had any luck w this? I am effectively doing the same thing.

I can get my Credit Card form to appear in with in my Order form,
however if the form doesn’t validate, all my Credit Card info is lost
and the user has to re-type it in. I believe it has something to do with
the my Order class (which extends Activerecord::Base) does not:
accepts_nested_attributes_for :credit_card

therefore the input names aren’t being created correctly, etc.

Thoughts?