LocalizableDb

Rails gem to localize your database.

If your application manage something like products or services that can be created dynamically, and you have to support multiple languages you may need to localize your database. LocalizableDb allow you to do that in a simple way.

Usage

I18n Integration.

Product.find(1) #=> #<Product id: 1, name: "luck">
Product.where(id: 1)
#=> <ActiveRecord::Relation [#<Product id: 1, name: "luck">]>

I18n.locale = :es

Product.l.find(1) #=> <Product id: 1, name: "suerte">
Product.l.where(id: 1)
#=> <ActiveRecord::Relation [#<Product id: 1, name: "suerte">]>

Specify the lenguage you want

Product.find(1) #=> <Product id: 1, name: "luck">
Product.where(id: 1)
#=> <ActiveRecord::Relation [#<Product id: 1, name: "luck">]>

Product.l(:es).find(1) #=> <Product id: 1, name: "suerte">
Product.l(:es).where(id: 1)
#=> <ActiveRecord::Relation [#<Product id: 1, name: "suerte">]>

Product.l(:pt).find(1) #=> <Product id: 1, name: "sortudo">
Product.l(:pt).where(id: 1)
#=> <ActiveRecord::Relation [#<Product id: 1, name: "sortudo">]>

Product.l(:fr).find(1) #=> <Product id: 1, name: "heureux">
Product.l(:fr).where(id: 1)
#=> <ActiveRecord::Relation [#<Product id: 1, name: "heureux">]>

Localize multiple languages

products = Product.where(id: 1)
products.inspect
#=> <ActiveRecord::Relation [#<Product id: 1, name: "luck">]>
products = Product.wl(:es,:pt,:fr).where(id: 1)
products.inspect
#=> <ActiveRecord::Relation [#<Product id: 1, name: "luck", es_name: "suerte", pt_name: "sortudo", fr_name: "heureux">]>

products.first.name #=> luck
products.first.attributes["es_name"] #=> suerte
products.first.attributes["pt_name"] #=> sortudo
products.first.attributes["fr_name"] #=> heureux

Creating

Product.create(name: "something", languages: {
    es: {name: "algo"},
    pt: {name: "alguma cosia"},
    fr: {name: "quelque chose"}
})
#=> #<Product id:2, name: "something">

Saving

Product.new(name: "love", languages: {
    es: {name: "amor"},
    pt: {name: "amor"},
    fr: {name: "amour"}
}).save
#=> #<Product id:3, name: "love">

love = Product.last
love.set_languages({
    es: {name: "amor :D"},
    pt: {name: "amor :D"},
    fr: {name: "amouuurt"}
})
love.save
#=> #<Product id: 3, name: "love">
love =  Product.l(:fr).find(3)
love.inspect
#=> #<Product id: 3, name: "amouuurt">

Updating

product = Product.find(3)
product.update(name: "the love", languages: {
    es: {name: "el amor"},
    pt: {name: "o amor"},
    fr: {name: "l'amour"}
})
#=> #<Product id:3, name: "the love">

product = Product.l(:fr).find(3)
product.inspect
#=> #<Product id: 3, name: "l'amour">

Eager loading support

products = Product.includes(:features).where(id: 1)
products.first.features.inspect
#=> <ActiveRecord::Relation [#<Feature id: 1, desc: "Makes people happy">]>

products = Product.l(:es) do |products|
    products.includes(:features)
end.where(id: 1)
products.first.features.inspect
#=> <ActiveRecord::Relation [#<Feature id: 1, desc: "Hace a la gente feliz">]>

Eager loading support for multiple languages

products = Product.includes(:features).where(id: 1)
products.first.features.inspect
#=> <ActiveRecord::Relation [#<Feature id: 1, desc: "Makes people happy">]>

products = Product.wl(:es,:pt,:fr) do |products|
    products.includes(:features)
end.where(id: 1)
products.first.features.inspect
#=> <ActiveRecord::Relation [#<Feature id: 1, desc: "Makes people happy", es_desc: "Hace a la gente feliz", pt_desc: "Faz as pessoas felizes", fr_desc: "Rend les gens heureux">]>

NOTE:

If you need to use aggregation functions or grouping stuff, use the raw model without calling the localize method (.l), otherwise a syntax error will be raised from ActiveRecord. We still working on this feature, if you want to help us, feel free to make a pull request :)

Installation

Add this line to your application's Gemfile:

gem 'localizable_db'

And then execute:

$ bundle

Then Install it!

$ rails g localizable_db:install

Configure your supported languages

# config/initializers/localizable_db_initializer_.rb
module LocalizableDb
  module Languages
    DEFAULT = :en
    SUPPORTED = [:en, :es] #=> Add your locales to this array.
  end
end

Generating

Generate a localizable model.

rails g localizable_db:model Product name:string desc:text other:string

Generate a migration for a localizable model.

rails g localizable_db:migration Product name:string desc:text other:string

Setting up your models

You need to call the localize method on your models, so localizable_db knows which attributes are localizable. Notice that the localizable attributes that you define in the model must have a column in the related localized table.

# app/models/product.rb
class Product < ApplicationRecord
    localize :name, :desc
end

Authors

yonga9121 | Nevinyrral

License

The gem is available as open source under the terms of the MIT License.