I’ve been trying to come up with a way to declare array constants in a class, and then present the members of the arrays as grouped options in a select control. The reason I am using array constants is because I do not want the options being backed by a database model.
This can be done in the basic sense rather easily using the grouped_collection_select view helper. What is not so straightforward is making this localizable, while keeping the original array entries in the background. In other words, I want to display the options in whatever locale, but I want the form to submit the original array values.
Anyway, I’ve come up with a solution, but it seems overly complex. My question is: is there a better way? Is a complex solution required, or have I overlooked a much easier solution?
I’ll explain my solution using a contrived example. Let’s start with my model class:
class CharacterDefinition < ActiveRecord::Base
HOBBITS = %w[bilbo frodo sam merry pippin]
DWARVES = %w[gimli gloin oin thorin]
@@TYPES = nil
def CharacterDefinition.TYPES
if @@TYPES.nil?
hobbits = TranslatableString.new('hobbits', 'character_definition')
dwarves = TranslatableString.new('dwarves', 'character_definition')
@@TYPES = [
{ hobbits => HOBBITS.map {|c| TranslatableString.new(c, 'character_definition')} },
{ dwarves => DWARVES.map {|c| TranslatableString.new(c, 'character_definition')} }
]
end
@@TYPES
end
end
The TranslatableString class does the translation:
class TranslatableString
def initialize(string, scope = nil)
@string = string;
@scope = scope
end
def to_s
@string
end
def translate
I18n.t @string, :scope => @scope, :default => @string
end
end
And the view erb statement look like:
<%= f.grouped_collection_select :character_type, CharacterDefinition.TYPES, 'values[0]', 'keys[0].translate', :to_s, :translate %>
With the following yml:
en:
character_definition:
hobbits: Hobbits of the Shire
bilbo: Bilbo Baggins
frodo: Frodo Baggins
sam: Samwise Gamgee
merry: Meriadoc Brandybuck
pippin: Peregrin Took
dwarves: Durin's Folk
gimli: Gimli, son of Glóin
gloin: Glóin, son of Gróin
oin: Óin, son of Gróin
thorin: Thorin Oakenshield, son of Thráin
The result is:

So, have I come up with a reasonable solution? Or have I gone way off the rails?
Thanks!
From the resounding silence my question received in response, I am guessing that there is not a better way. Anyway, the approach works and I am sticking to it until I discover something better.