# Traco [![Build Status](https://secure.travis-ci.org/barsoom/traco.png)](http://travis-ci.org/barsoom/traco) Translatable attributes for Rails 3 and 4 (Ruby 1.9+), stored in the model table itself. Inspired by Iain Hecker's [translatable_columns](https://github.com/iain/translatable_columns/). To store translations outside the model, see Sven Fuchs' [globalize3](https://github.com/svenfuchs/globalize3). ## Usage Say you want `Post#title` and `Post#body` to support both English and Swedish values. Write a migration to get database columns with locale suffixes, e.g. `title_sv` and `title_en`, like: ```ruby class CreatePosts < ActiveRecord::Migration def change create_table :posts do |t| t.string :title_sv, :title_en t.text :body_sv, :body_en t.timestamps end end end ``` Don't create a database column named `title` without a suffix, since Traco will define a method with that name. If you use a locale format like `pt-BR`, the column name would be `title_pt_br`. Declare the attributes in the model: ```ruby class Post < ActiveRecord::Base translates :title, :body end ``` You can still use your accessors like `title_sv` and `title_sv=` in forms, validations and other code, but you also get: `#title`: Shows the title in the current locale. If blank, falls back to default locale. Otherwise nil. `#title=`: Assigns the title to the column for the current locale, if present. Raises if the column doesn't exist. `.human_attribute_name(:title_sv)`: Extends this standard method to return "Title (Swedish)" if you have a translation key `i18n.languages.sv = "Swedish"` and "Title (SV)" otherwise. Rails uses this method to build validation error messages and form labels. `.translatable_attributes`: Returns an array like `[:title, :body]`. `.locale_columns(:title)`: Returns an array like `[:title_sv, :title_en]` sorted with default locale first and then alphabetically. Suitable for looping in forms: ```erb <% Post.locale_columns(:title).each do |column| %>

<%= form.label column %> <%= form.text_field column %>

<% end %> ``` Or perhaps for things like: ```ruby attr_accessible *locale_columns(:title) validates *locale_columns(:title), :uniqueness => true ``` You can also pass multiple attributes if you like: ```ruby attr_accessible *locale_columns(:title, :body) ``` The return value will be sorted like `[:title_sv, :title_en, :body_sv, :body_en]`. `.locales_for_attribute(:title)`: Returns an array like `[:sv, :en]` sorted with default locale first and then alphabetically. And the equivalent methods for `body`, of course. Please note that your `translates :title, :body` declaration must be called before you call `locale_columns`. Otherwise you will get an error like "NoMethodError: undefined method `locale\_columns' for #\". ### Disable fallback if you specify ```ruby class Post < ActiveRecord::Base translates :title, :body, fallback: false end ``` then `#title` will return `nil` if there is no translation in the current locale, instead of falling back to the default locale. ### Overriding methods Methods are defined in an included module, so you can just override them and call Traco's implementation with `super`: ```ruby class Post < ActiveRecord::Base translates :title def title super.reverse end end ``` ## Installation Add this to your `Gemfile`: ```ruby gem 'traco' ``` Then run bundle to install it. ## Running the tests bundle rake ## Credits and license By [Barsoom](http://barsoom.se) under the MIT license: > Copyright (c) 2012 Barsoom AB > > Permission is hereby granted, free of charge, to any person obtaining a copy > of this software and associated documentation files (the "Software"), to deal > in the Software without restriction, including without limitation the rights > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell > copies of the Software, and to permit persons to whom the Software is > furnished to do so, subject to the following conditions: > > The above copyright notice and this permission notice shall be included in > all copies or substantial portions of the Software. > > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN > THE SOFTWARE.