# Active Record, Migration, and Translation

**URL:** <https://www.ruby-forum.com/t/active-record-migration-and-translation/122188>\
**Category:** Rails\
**Created:** [December 5, 2007, 11:35am UTC](https://www.ruby-forum.com/t/active-record-migration-and-translation/122188 "2007-12-05T11:35:02Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![SSSSSbastien\_Lamy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/bb73d2/32.png) [@SSSSSbastien\_Lamy](https://www.ruby-forum.com/u/SSSSSbastien_Lamy)\
**Post date:** [December 5, 2007, 11:35am UTC](https://www.ruby-forum.com/t/active-record-migration-and-translation/122188/1 "2007-12-05T11:35:02Z")

</div>

Hi,

I think the columns and table in migration should be able to have an  
optional “display\_name” set manually. Something like:

create\_table :people, {display\_name =\> “Personne”} do |t|  
t.column :first\_name :string, :display\_name =\> “Prénom”.  
end

Let me explain my point of view:

Rails is a framework made to write programs in English. You see it when  
you are confronted to the pluralization rules, or the \_confirmation  
fields.  
I think this is okay, because programming Rails without speaking English  
is a pain anyway: most of the docs and tutorial available on the web are  
in English, and all functions have english name.

But where I think Rails goes a little bit too far, is that it is also  
meant to be a lot more easy using it to write application with english  
output, for English-speaking user. And if programmers are writing for  
non-English user, it’s a lot more pain for them. I think this is not  
fair. World is not just english-speaking, and Rails is a world-wide open  
software.

And I think it would not be difficult for Rails to make it easy  
programming a non-english output.

For the translations of the error messages, I found that  
localisation\_simplified is a very nice and very lightweight plugin that  
should be integrated in Rails by default. This would spare programmers  
the pain to check all plugins availables at  
[http://wiki.rubyonrails.org/rails/pages/InternationalizationComparison](http://wiki.rubyonrails.org/rails/pages/InternationalizationComparison)  
when they only want one language output, but non-english.

But this plugin does not offer a solution to translate the database  
fields, so generated scafold is all in english, and I have to correct  
all the rhtml files manually  
Moreover, I’m still displaying error messages like:  
“First name est un champs obligatoire.”  
So I have to write all error messages manually, repeating myself a lot.  
Using gettext or internationalisation plugin to solve this problem makes  
me feel like taking a hammer to kill a bee: I just want one language  
output.

Scaffolding is such a good part of rails, that it should also be fully  
enjoyable for programmers wanting a non-english-output!

To solve this, my first thought was to write my database in my target  
language (French). But then I was confronted to the pluralization  
problem, and the “\_confirmation” things. Moreover, all functions of the  
framework are in English. So when I’m writing something like  
“utilisateur.create”, I find it ugly, and I feel like neither English  
nor French programmer would understand what I meant when I wrote this.  
As I said, Rails is meant to be programmed in full-english.

So if I write my database in English, and want the user to see it in  
french, then I have to put the translation somewhere. And if I change or  
create or delete a field in my database, I also have to change, create  
or delete the translation. (and I don’t want to repeat myself).

This is why I think the best place for translation is in migration: this  
is where we are defining what will be the name of the fields in the  
database, so it’s the best place to define the name we want it to be  
displayed in the app.

The perfect thing would be just one more option, available for every  
kind of fields:

create\_table :people, {display\_name =\> “Personne”} do |t|  
t.column :first\_name :string, :display\_name =\> “Prénom”.  
end

If default scaffold behaviour is able to understand this, we’re done.  
This feature would also be very useful to people with ugly existing  
database that they’re just not allowed to touch.

And this would also help for globalisation: I would then be able to  
write:  
t.column :first\_name :string, display\_name =\> translate(“First Name”).

And if you don’t give a display name, you’ve just got the default  
behaviour with the “humanize” thing.

I know this is not very compatible with the “sexy migration” of rails  
2.0, but I think there is a lot of people for who this feature would be  
more useful than the “sexy migration” one.

Hope I conviced someone able to do this!

Sebastien.

---

<div class="post-metadata">

**Author:** ![SSSSSbastien\_Lamy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/bb73d2/32.png) [@SSSSSbastien\_Lamy](https://www.ruby-forum.com/u/SSSSSbastien_Lamy)\
**Post date:** [December 5, 2007, 2:27pm UTC](https://www.ruby-forum.com/t/active-record-migration-and-translation/122188/2 "2007-12-05T14:27:44Z")

</div>

on a related note, I’d like to be able to display a more friendly  
filed name than the table column in the form validation error message.  
i.e., I want to say

validates\_format\_of :column\_name  
:with =\> /^[a-z0-9]\*$/i,  
:message =\> ‘friendly name should be keywords separated by spaces.  
Keywords should be letters and numbers only’

but I end up with the column\_name stuck in front of the message. is  
there a workaround (renaming the column isn’t an option.)

---

<div class="post-metadata">

**Author:** ![SSSSSbastien\_Lamy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/bb73d2/32.png) [@SSSSSbastien\_Lamy](https://www.ruby-forum.com/u/SSSSSbastien_Lamy)\
**Post date:** [December 8, 2007, 2:57pm UTC](https://www.ruby-forum.com/t/active-record-migration-and-translation/122188/3 "2007-12-08T14:57:10Z")

</div>

To change the error messages, you can use override the fuction  
“errormessage” as shown below. Place a file containing the new code in  
the “lib” directory.  
Then require this file in your config/environment.rb  
(ie, if your file is named "my\_custem\_error\_message.rb’, put require  
‘my\_custom\_error\_message\_file’ in config/environment.rb)  
Here I give you the code used by the “localisation\_simplified” plugin,  
you can change it to fill your special needs.

module ActionView  
module Helpers

```
 #Modify ActiveRecord to use error message headers (text from 

```

lang-file)  
module ActiveRecordHelper  
alias\_method :old\_error\_messages\_for, :error\_messages\_for

```
   def error_messages_for(*params)
     options = params.last.is_a?(Hash) ? params.pop.symbolize_keys : 

```

{}  
objects = params.collect {|object\_name|  
instance\_variable\_get("@#{object\_name}") }.compact  
count = objects.inject(0) {|sum, object| sum +  
object.errors.count }  
unless count.zero?  
html = {}  
[:id, :class].each do |key|  
if options.include?(key)  
value = options[key]  
html[key] = value unless value.blank?  
else  
html[key] = ‘errorExplanation’  
end  
end  
messages = ActiveRecord:: Errors.default\_error\_messages  
if options[:action]  
header\_message = pluralize(count,  
messages[:error\_forbid])+’ '+options[:action]  
else  
header\_message = format( messages[:error\_header],  
pluralize(count, messages[:error\_translation]),  
(options[:object\_name] ||  
params.first).to\_s.gsub("\_", " "))  
end  
error\_messages = objects.map {|object|  
object.errors.full\_messages.map {|msg|content\_tag(:li, msg) } }  
content\_tag(:div,  
content\_tag(options[:header\_tag] || :h2, header\_message) \<\<  
content\_tag(:p, messages[:error\_subheader]) \<\<  
content\_tag(:ul, error\_messages),  
html  
)  
else  
‘’  
end  
end  
end  
end  
rubynuby a écrit :

---

<div class="post-metadata">

**Author:** ![SSSSSbastien\_Lamy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/bb73d2/32.png) [@SSSSSbastien\_Lamy](https://www.ruby-forum.com/u/SSSSSbastien_Lamy)\
**Post date:** [December 8, 2007, 10:27pm UTC](https://www.ruby-forum.com/t/active-record-migration-and-translation/122188/4 "2007-12-08T22:27:45Z")

</div>

Frederick C. a écrit :

> > Keywords should be letters and numbers only’  
> > …  
> > end  
> > end  
> > end

This is what I’m doing, but I wrote my message to say there should be a  
better way: I have to write two times the attribute name: one for column  
definition, one for translation definition. So if it changes I have to  
correct it two times also.

---

<div class="post-metadata">

**Author:** ![SSSSSbastien\_Lamy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/bb73d2/32.png) [@SSSSSbastien\_Lamy](https://www.ruby-forum.com/u/SSSSSbastien_Lamy)\
**Post date:** [December 8, 2007, 3:50pm UTC](https://www.ruby-forum.com/t/active-record-migration-and-translation/122188/5 "2007-12-08T15:50:24Z")

</div>

On 5 Dec 2007, at 13:27, rubynuby wrote:

> on a related note, I’d like to be able to display a more friendly  
> filed name than the table column in the form validation error message.  
> i.e., I want to say
> 
> validates\_format\_of :column\_name  
> :with =\> /^[a-z0-9]\*$/i,  
> :message =\> ‘friendly name should be keywords separated by spaces.  
> Keywords should be letters and numbers only’

Well looking in validations.rb, it looks like full\_error\_messages uses  
calls human\_attribute\_name. By default this just does things like  
convert first\_name to First name, but you could imagine something like

class Person \< AR::Base  
def self.human\_attribute\_name(attr\_name)  
case attr\_name  
when ‘first\_name’ then ‘Prénom’  
…  
end  
end  
end

---

<div class="post-metadata">

**Author:** ![SSSSSbastien\_Lamy](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/bb73d2/32.png) [@SSSSSbastien\_Lamy](https://www.ruby-forum.com/u/SSSSSbastien_Lamy)\
**Post date:** [December 8, 2007, 10:32pm UTC](https://www.ruby-forum.com/t/active-record-migration-and-translation/122188/6 "2007-12-08T22:32:26Z")

</div>

On 8 Dec 2007, at 21:29, Sébastien Lamy wrote:

> > > validates\_format\_of :column\_name
> 
> be a  
> better way: I have to write two times the attribute name: one for  
> column  
> definition, one for translation definition. So if it changes I have to  
> correct it two times also.

I don’t think it can be in the migration (how’s the model going to  
know at runtime?), but overwriting human\_name is a chore.  
If you could write

class Person \< AR::Base  
display :first\_name, :as =\> ‘Prénom’  
end

Then it would be less tedious.

Fred
