A variant on the acts_as_localized
theme for when you have static seed data in your system that must be localised.
- It's designed for a specific use-case, namely the localisation of your seed data.
- It works with the standard Rails I18n system and assumes you already have a lot of your localisation data in
config/locales/*.yml
, or you have youri18n
stuff already set up in a database. - It's fast and easy.
In your Gemfile
gem 'acts_as_read_only_i18n_localised'
In config/locales/categories.en.yml
en:
categories:
fruits:
name: Great fresh fruit
description: Our fantastic range of seasonal and local fresh fruit will delight you.
vegetables:
name: Farm fresh veggies
description: Our locally grown and freshly harvested veggies are simply delicious.
meats:
name: Farm-fresh seasonal meat
description: >-
Loved in life then lightly killed, our meat is locally sourced from small farms
that meet our demanding standards.
In app/models/category.rb
class Category < ActiveRecord::Base
include ActsAsReadOnlyI18nLocalised
validates :slug, format: {with: /\A[a-z]+[-?[a-z]]\z/},
uniqueness: true,
presence: true
has_many :products
validates_associated :products
acts_as_read_only_i18n_localised :name, :description
end
This simply generates appropriate name
and description
methods along the lines of
def name
key = "#{self.table_name}.#{slug}.name".downcase.to_sym
return I18n.t(key)
end
with the effect that a call to category.name
will always return the localised name using the standard I18n
system.
Depending on how your code is configured, I18n
will raise a MissingTranslationData
exception if the key does correspond to any data. Exceptions on missing keys is usually turned on in development
and test
but not on staging
or production
. See The Rails I18n Guide for more.
Note: acts_as_read_only_i18n_localised
will also work with non active-record
classes. If there is no self.table_name
method it will check to see if the class.name
responds to pluralize
, and use that if it can, otherwise it will just use the class.name
.
Say your categories
have their own sub categories
. Building on the previous example you might define the following
class Category < ActiveRecord::Base
include ActsAsReadOnlyI18nLocalised
validates :slug, format: {with: /\A[a-z]+[-?[a-z]]\z/},
uniqueness: true,
presence: true
has_many :products
validates_associated :products
has_many :categories, foreign_key: :parent_id
belongs_to :parent, class_name: 'Category'
acts_as_read_only_i18n_localised :name, :description
use_custom_slug :slug_maker
def slug_maker
reurn slug if parent.nil?
"#{@parent.slug}.categories.#{slug}"
end
end
In db/seeds.rb
add something like
require 'i18n'
I18n.t(:categories).each do |key, data|
Category.create(slug: key)
end
In db/seeds.rb
add something like
require 'i18n'
I18n.t(:categories).each do |key, data|
cat = Category.where(slug: key).first_or_create!
if data[:categories]
data[:categories].each do |inner_key, inner_data|
Category.where(slug: inner_key, parent: cat).first_or_create!
end
end
end
Or preferably something recursive, though the above will do if you are only going 1 level deep.
This gem requires Ruby version 2.0.0 or better. It is tested against the following Rubies.
2.0.0
2.1.6
2.2.4
2.3.0
Before you do anything do this:
bundle install
gem build acts_as_read_only_i18n_localised.gemspec
rspec
or
rake
You can also run the following QA tools against the codebase if you have them installed.
rubocop
(on its own without any of thecodeclimate
stuff.)codeclimate
(which will also runrubocop
itself.)
Contributions and ideas are welcome.
If you have ideas on how to improve the codebase or feature-set, please add them as issues so they can be discussed.
For contributing code please see CONTRIBUTING for details on how to do that.