Matching available languages to language names

HansCz picture HansCz · Oct 5, 2009 · Viewed 7.3k times · Source

I want to make a language selection dropdown in a site user edit/create page.

For this purpose, I have of course translated the site to more than one language. Using I18n.available_languages, I can then get an array of locale codes, like so

development environment (Rails 2.3.4)
> I18n.available_locales
   => [:en, :da]

Furthermore, I have created a Language model and related it to User:

# app/models/language.rb
class Language < ActiveRecord::Base
  has_many :users  
end

# app/models/user.rb
class User < ActiveRecord::Base
  belongs_to :language  
end

# db/schema.rb
create_table "languages", :force => true do |t|
  t.string "name"
  t.string "code"
end

create_table "users", :force => true do |t|
  t.integer  "language_id"
end

The language table then contains a locale code and a language name in the native tongue, like so:

| id  | name                | code |
------------------------------------
| 28  | Dansk               | da   |
| 29  | Nederlands          | nl   |
| 30  | English             | en   |
| 31  | Esperanto           | eo   |

I then have the following assignment in the User new, create and edit actions:

# app/controllers/users_controller.rb (extract)
@available_languages = I18n.available_locales.collect {|language_code| Language.find_by_code(language_code.to_s)}

which I use in the view like so ('available_languages' is a local variable, since @available_languages from the controller has been passed to a partial):

# app/views/users/_form.haml (extract)
= f.collection_select(:language_id, available_languages, :id, :name, {:prompt => true})

The upshot of all this, is that the user will get a locale select dropdown to define the locale for the given user.

My question is: Is there a clean way to move the @available_languages assignment out of the UsersController and into the Language model, so I can shorten this:

@available_languages = I18n.available_locales.collect {|language_code| Language.find_by_code(language_code.to_s)}

to something like this:

@available_languages = Language.translations_available

Answer

dwaynemac picture dwaynemac · Jan 20, 2010

I add a "locale_name" key to each yml with it's language name in it's own language as well. For example:

in es-AR.yml

es-AR:
  locale_name: "Castellano"

in en.yml

en:
  locale_name: "English"