En rails 2.3.4 je trouve le comportement du error_messages un peu surprenant avec les formulaires imbriqués.

class Person < ActiveRecord::Base
  accepts_nested_attributes_for :address, :allow_destroy => true
end
class Person < ActiveRecord::Base
  validates_presence_of :label
end
<% form_for(@person) do |f| -%>
  <% f.fields_for :address do |address| %>
    <p>
      <%= address.label :label %>
      <%= address.text_field :label %>
    </p>
  <% end -%>
<% end -%>

D'après http://weblog.rubyonrails.org/2009/1/26/nested-model-forms, les erreurs sont recopiées dans l'objet parent. Ils disent que c'est sujet à changement mais apparement c'est toujours le cas. En créant les objets depuis la console:

>> p  = Person.new
>> p.build_address
>> p.save
>> p.errors
=>
#<ActiveRecord::Errors:0x102d94560 @errors={"address_label"=>[#<ActiveRecord::Error:0x102d7be48 …

Du coup dans mon fichier de traduction je mets logiquement:

person:
  address_label: "foo"

Perdu ! En maintant les mains dans le cambouis vendor/rails je suis remonté jusqu'à generate_full_message qui se base en fait sur la classe de base de l'objet (imbriqué ou non). Du coup il va chercher dans:

address:
  address_label: "foo"

C'est pas vraiment logique, surtout que dans 99% des cas on a déjà la traduction:

address:
  label: "foo"

Ce serait cool s'il pouvait aller le chercher là.
Ah et interdiction de répondre t-as-qu-a-faire-un-patch :-)