Unit tested example
Here’s a Unit Test (you do know how to test your Rails app, right?) which shows a way to work with the Globalize plugin. Far easier than playing around in the console to see if you can get it to work.
Ensure compatability
Globalize uses its own models – e.g. Language, Country and Translation. If you have models or database tables with these names, they might conflict with testing later on. Better now create a migration to rename these tables and then rename the models, and you’ll be fine.
Install Globalize
In your RAILS_ROOT, execute the following to install the Globalize plugin.
script/plugin install http://svn.globalize-rails.org/svn/globalize/globalize/trunk
Create the model
The test assumes the presence of a model called Newsitem. So go ahead and generate the model and modify it like so:
class Newsitem < ActiveRecord::Base
translates :title, :excerpt, :body
end
See the Globalize API docs for translates. Basically, it means Globalize will give the specified columns special treatment.
Create the table
The following migration might help you create the table:
class AddNewsTable < ActiveRecord::Migration
def self.up
create_table :newsitems do |t|
t.column :title, :string
t.column :excerpt, :string
t.column :body, :text
t.column :lock_version, :integer, :default => 0
t.column :user_id, :integer
t.column :updated_at, :datetime
t.column :created_at, :datetime
end
end
def self.down
drop_table :newsitems
end
end
You’re ready to migrate the table into your database by running rake migrate. Of course, not all columns are needed for this example, but it might be an incentive to find the meaning of one or two things in the Rails API.
Globalize it
script/generate globalize tiny
rake migrate
This will take a while. You have been warned.
Setup the test fixtures
You need to tell globalize which languages/countries it should know about. The previous migration made sure to fill up the globalize tables with a large number of preconfigured languages and countries all ready for you to use in your development database.
However as we are using the test database, you’ll need to create fixtures for the globalize tables. You can either create them from scratch (Have a look at the globalize tables in your dev tables) or copy over the fixtures used in globalize’s own test which are located in the test directory
vendor/plugins/globalize/test/fixtures/globalize_languages.yml
#You only really need the languages fixtures but chances are
#you'll want to copy over these two as well for more tests
vendor/plugins/globalize/test/fixtures/globalize_countries.yml
vendor/plugins/globalize/test/fixtures/globalize_translations.yml
The globalize test fixtures do not include dutch so you’ll have to add it in for the newsitem_test (or you could just modify the test to use any of the languages in the fixtures):
#globalize_languages.yml
...
dutch:
id: 7
iso_639_1: nl
iso_639_2: nld
english_name: Dutch
native_name: Nederlands
scope: L
macro_language: false
pluralization: 'c == 1 ? 1 : 2'
#globalize_countries.yml
...
holland:
id: 6
code: NL
english_name: Netherlands
currency_format: '€ %n'
currency_code: EUR
thousands_sep: '.'
decimal_sep: ','
currency_decimal_sep: '.'
The Unit Test
First of all, this is not a real unit test. It’s just an easy way to show you how to work with Globalize.
When you generated your model, the rails command was smart enough to create a test for it. You can find the test in RAILS_ROOT/test/unit/newsitem_test.rb. Just copy the paste below and replace the content of the original file with it.
require File.dirname(__FILE__) + '/../test_helper'
class NewsitemTest < Test::Unit::TestCase
def test_add_content_translations
Newsitem.delete_all
Globalize::Locale.set_base_language('en-US')
# create a row in the base language
Globalize::Locale.set('en-US')
assert_nothing_raised() do
assert_kind_of Newsitem, Newsitem.create!(:title => 'US Title',
:excerpt => 'US excerpt',
:body => 'US body copy')
end
assert_equal 1, Newsitem.find(:all).size
# retrieve row
newsitem = Newsitem.find(:first)
assert_kind_of Newsitem, newsitem
assert_equal 'US Title', newsitem.title
# create a translation by switching the locale and updating attributes
Globalize::Locale.set('nl-NL')
# newsitem.title = 'NL Titel'
# newsitem.excerpt = 'NL samenvatting.'
# newsitem.body = 'NL Broodtekst.'
# assert_nothing_raised() {newsitem.save!}
# either use the commented out code above or the line below
# You cannot fetch a row in one language and save it in another.
# So just switch language, fetch again, and then update_attributes
newsitem = Newsitem.find(:first)
newsitem.update_attributes(:title => 'NL Titel',
:excerpt => 'NL samenvatting.',
:body => 'NL broodtekst')
# check if the translated row has been saved
assert_equal 'NL Titel', newsitem.title
# check if the base language row still exists
Globalize::Locale.set('en-US')
# now see if the example from the wiki gives the expected result
newsitem = Newsitem.find(:first)
assert_equal 'US Title', newsitem.title
Globalize::Locale.set('nl-NL')
newsitem = Newsitem.find(newsitem.id)
assert_equal 'NL Titel', newsitem.title
end
def test_add_string_translations
Globalize::Locale.set_base_language('en-US')
Globalize::Locale.set('en-US')
language = Globalize::Language.pick 'nl-NL'
Globalize::Locale.set_translation(
"This is written in English",
language,
"Dit is geschreven in het Nederlands"
)
assert_equal 'This is written in English', "This is written in English".t
Globalize::Locale.set('nl-NL')
assert_equal 'Dit is geschreven in het Nederlands', "This is written in English".t
end
end
Run the test
From your RAILS_ROOT, run the test. The expected result should be something like shown below.
aluminum:~/dev/projects/my_app/trunk charles$ ruby test/unit/newsitem_test.rb
Loaded suite test/unit/newsitem_test
Started
..
Finished in 1.986655 seconds.
2 tests, 10 assertions, 0 failures, 0 errors
aluminum:~/dev/projects/my_app/trunk charles$
Help!
If you have more questions, you can find us in #globalize on Freenode or on the Rails mailing list. Make sure the first word of your subject line is Globalize, so your message is easier to spot.
revision 1 · 02.06.09 16:27 · by: Marko Seppä