# Rails3: Should nested ActiveModel be treated like nested ActiveRecord

**URL:** <https://www.ruby-forum.com/t/rails3-should-nested-activemodel-be-treated-like-nested-activerecord/193244>\
**Category:** Rails\
**Created:** [August 13, 2010, 11:17pm UTC](https://www.ruby-forum.com/t/rails3-should-nested-activemodel-be-treated-like-nested-activerecord/193244 "2010-08-13T23:17:26Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![tnyplz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/f17d59/32.png) [@tnyplz](https://www.ruby-forum.com/u/tnyplz)\
**Post date:** [August 13, 2010, 11:17pm UTC](https://www.ruby-forum.com/t/rails3-should-nested-activemodel-be-treated-like-nested-activerecord/193244/1 "2010-08-13T23:17:26Z")

</div>

I have an User model (ActiveRecord). It has many Addresses  
(ActiveRecord) and one CreditCard (ActiveModel)

When I submit my nested form the CreditCard validations did not fire.

So… in my User model I added this so the credit card validations  
would get called.

def before\_validation  
credit\_card.valid? unless credit\_card.nil?  
return true  
end

This worked great. the missing credit card fields were highlighted  
and everything… except

@user.errors.full\_messages only contained errors for the user and  
addresses.

So I updated my before\_validation call again

def before\_validation  
credit\_card.valid? unless credit\_card.nil?  
credit\_card.errors.each{|k,v|  
errors[“credit\_card.#{k}”] = v  
}  
return true  
end

Now everything is cool except the ugly error messages that nested  
forms give you.

I chop off the credit card and addresses prefix when displaying them

```
  <% @user.errors.full_messages.each do |msg| %>
    <%
    message = msg.gsub(/Credit card /, '').capitalize
    message = message.gsub(/Addresses /, '').capitalize
  %>
    <li><%= message %></li>
  <% end %>

```

This seems like a lot of work and I suspect there is a 1 liner I’m  
missing that will make this all automatic.

Something like this in my user model.

has\_one\_virtual :credit\_card

Does such a thing exist? I hope so 🙂

================== Code snippets ====================

==== User model ====

class User \< ActiveRecord::Base  
acts\_as\_authentic  
has\_many :addresses  
accepts\_nested\_attributes\_for :addresses  
validates :credit\_card, :presence =\> true  
attr\_accessor :email\_confirmation, :credit\_card

validates\_confirmation\_of :email, :message =\> “should match  
confirmation”

def credit\_card\_attributes=(attributes)  
self.credit\_card = CreditCard.new(attributes)  
end

def before\_validation  
credit\_card.valid? unless credit\_card.nil?  
credit\_card.errors.each{|k,v|  
errors[“credit\_card.#{k}”] = v  
}  
return true  
end  
end

==credit\_card=================  
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, :presence =\> true  
validates :card\_number, :presence =\> true  
validates :card\_verification, :presence =\> true  
validates :card\_expires\_on, :presence =\> true  
validates :agree, :presence =\> true

def initialize(attributes = {})  
expire\_date = {}  
attributes.each do |name, value|  
if name.include?(‘card\_expires\_on’)  
expire\_date[name] = value  
else  
send("#{name}=", value)  
end  
end  
# yeah, this is a total mess. Can ActiveModel handle this?  
ymd = expire\_date.map(&:last).map(&:to\_i)  
begin  
send(“card\_expires\_on=”, Time.zone.local(ymd[2], ymd[1],1))  
unless ymd[1].blank? || ymd[2].blank?  
rescue  
end  
end

def persisted?  
false  
end  
end

---

<div class="post-metadata">

**Author:** ![tnyplz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/f17d59/32.png) [@tnyplz](https://www.ruby-forum.com/u/tnyplz)\
**Post date:** [August 16, 2010, 8:04pm UTC](https://www.ruby-forum.com/t/rails3-should-nested-activemodel-be-treated-like-nested-activerecord/193244/2 "2010-08-16T20:04:59Z")

</div>

(I’m still looking for some feedback on an equivalent way to do  
accepts\_nested\_attributes for nested resources that are  
ActiveModels… instead of the hack I have below).

For the bad error message formatting…instead of stripping the  
prefixes from the error messages I could use l18n

> ```
> <% @user.errors.full_messages.each do |msg| %>
> <%
> message = msg.gsub(/Credit card /, '').capitalize
> message = message.gsub(/Addresses /, '').capitalize
> %>
> <li><%= message %></li>
> <% end %>
> 
> ```

after some trial and error I figured out how to to make l18n with  
nested resources.

en:  
activerecord:  
attributes:  
user:  
credit\_card:  
agree: “Agreement”  
card\_verification: “Card Verification Value”  
addresses:  
address1: “Street Address”

I’ll probably stick to using gsub for most cases (until I start  
localizing all my text). Unless of course there is an automatic way  
to make “Credit card card verification can’t be blank” display “Card  
verification can’t be blank”
