I18n translations for non Active Record models

In a current project at work I constantly need some collections of values for objects, which I like to be encapsulated. So I am using non AR models. But when it comes to translation, e.g. for select boxes, this becomes a little bit tricky. This is my approach.

Lerne mehr über Ruby on Rails mit Martin Labuschins
Ruby on Rails Link Library.

Disclaimer: Another way is just to add a new AR model to manage those values by a database table. But since the values heavily affect business-logic, I prefer a fixed database independent solution: non AR models.

This is a non AR model to maintain reasons for a non interested shop owner in our upcoming internal sales application:

class NoInterestReason
  attr_reader :name

  def self.all
    types = [
      "too_expensive",
      "happy_with_competitor",
      "inappropriate_timing",
      "no_special_reason",
      "relaunch_in_progress",
      "soon_out_of_business"
    ].sort
    types.map { |name| new(name) }
  end

  def initialize(name)
    @name = name
  end
end

My colleagues from our sales department now need to select a reason if the shop owner is not interested in our services. This is important for future reports as well as recycling¹ those shop owners in a particular time distance. So I added a collection_select for those reasons like this:

<% fields_for "company[activity_attributes][]", Activity.new do |activity_form|%>
  ...
  <%= activity_form.label :kind, t(:kind) %>
  <%= activity_form.collection_select :no_interest_reason, NoInterestReason.all, :name, :name %>
  ...
<% end %>

To translate the contents of the option-elements there are three steps:

1. Add translations to the locale file

de:
  ...
  too_expensive: "zu teuer"
  happy_with_competitor: "bereits mit Kokurrent zufrieden"
  inappropriate_timing: "unpassendes Timing"
  no_special_reason: "kein besonderer Grund"
  relaunch_in_progress: "Relaunch in Arbeit"
  soon_out_of_business: "Shop wird bald geschlossen"

2. Add this instance method to the NoInterestReason model

class NoInterestReason
  ...
  def translate
    I18n.t(name, :default => name)      
  end
end

The default value will be used if no translation is available.

3. Use the new method name as 4th argument of the collection_select call

<% fields_for "company[activity_attributes][]", Activity.new do |activity_form|%>
  ...
  <%= activity_form.collection_select :no_interest_reason, NoInterestReason.all, :name, :translate %>
  ...
<% end %>

Now the options are translated to the current language while the saved values are still in my desired language independent schema. I hope, this approach is helpful for other developers, too.


¹ This is by far no disrespectful expression, rather every shop owner simple runs through a defined Lifecycle

veröffentlicht am 10.03.2011 um 15:49 von Martin Labuschin in , , ,

blog comments powered by Disqus
The Ruby on Rails Link Library Spanning Sync SEO-Dokumentation Gowalla
ProWebApps WellDone (β) Pinboard (α) Netzwerk Münsterland
Blogs Bücher Frameworks iPhone Mac Web-Apps