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.find(1) #=> <Product id: 1, name: "suerte">
Product.where(id: 1)
#=> <ActiveRecord::Relation [#<Product id: 1, name: "suerte">]>
Product.l.find(1) #=> <Product id: 1, name: "suerte">
Product.l.where(id: 1)
#=> <ActiveRecord::Relation [#<Product id: 1, name: "suerte">]>
Specify the language 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.l(: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.get_name #=> luck
products.first.get_name(:es) #=> suerte
products.first.get_name(:pt) #=> sortudo
products.first.get_name(:fr) #=> heureux
products.first.attributes["es_name"] #=> suerte
products.first.attributes["pt_name"] #=> sortudo
products.first.attributes["fr_name"] #=> heureux
Creating
Product.create(name: "something", product_languages_attributes: [{
{name: "algo", locale: "es"},
{name: "alguma cosia", locale: "pt"},
{name: "quelque chose", locale: "fr"}
}])
#=> #<Product id:2, name: "something">
Saving
Product.new(name: "love", product_languages_attributes: [{
{name: "algo", locale: "es"},
{name: "alguma cosia", locale: "pt"},
{name: "quelque chose", locale: "fr"}
}]).save
#=> #<Product id:3, name: "love">
love = Product.last
love.product_languages.build([
{name: "algo", locale: "es"},
{name: "alguma cosia", locale: "pt"},
{name: "quelque chose", locale: "fr"}
])
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", product_languages_attributes: [{
{name: "algo", locale: "es"},
{name: "alguma cosia", locale: "pt"},
{name: "quelque chose", locale: "fr"}
}])
#=> #<Product id:3, name: "the love">
product = Product.l(:fr).find(3)
product.inspect
#=> #<Product id: 3, name: "l'amour">
Destroying
Product.find(1).destroy
# begin transaction
# SELECT "product_languages".* FROM "product_languages" WHERE "product_languages"."localizable_object_id" = ? [["localizable_object_id", 1]]
# DELETE FROM "product_languages" WHERE "product_languages"."id" = ? [["id", 1]]
# DELETE FROM "products" WHERE "products"."id" = ? [["id", 1]]
# commit transaction
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).includes.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.l(:es,:pt,:fr).includes(:features).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">]>
Aggregation and grouping stuff operations work as usual
Product.count
# => 3
Product.l(:es,:pt,:fr).count
# => 3
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, default language and other the behavior of the gem.
# config/initializers/localizable_db_initializer_.rb
LocalizableDb.config do |config|
# REQUIRED
config.supported_languages = [:en, :es, :pt, :fr]
config.default_language = :en
# OPTIONAL
# config.enable_i18n_integration = true
# enable_i18n_integration Allow you to use the eager load methods (includes, preload and eager_load)
# as in the examples. If you set this option to false then eager load methods will not work and
# you will have to call the ::l method to localize the language you want.
# config.enable_getters = true
# enable_getters Allow you to use the getters methods to access the localized attributes.
# config.attributes_integration = true
# attributes_integration overrides the attributes of the model with the localized attributes.
# Example:
# Imagine you have a Product like this one
# #<Product id: 1, name: "love">
# with this configuration
# Product < ApplicationRecord
# localize :name
# end
# When you retrieve the product of name love in spanish from your database, and this option is set to true
# it will return
# #<Product id: 1, name: "amor">
# If this option is set to false, the retrieved object will be
# #<Product id: 1, name: "love">
# an you will find the "es_name" into the #attributes hash
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
License
The gem is available as open source under the terms of the MIT License.