globalize3 translating gem: What do I do about attributes that don't need translation (in writing migration)?

StackOverflow https://stackoverflow.com/questions/12467957

質問

The github page for the globalize3 gem, https://github.com/svenfuchs/globalize3, clearly outlines how to prep a model's migration with string and text attributes that you would want multiple translations of. eg:

 class CreatePosts < ActiveRecord::Migration
   def up
     create_table :posts do |t|
     t.timestamps
   end
   Post.create_translation_table! :title => :string, :text => :text
 end
 def down
   drop_table :posts
   Post.drop_translation_table!
 end
 end

What about if I have certain attributes that don't require translation - such as saving a user_id or other integer-value attributes. Do I write them below as part of the Post.create_translation_table! declaration, or leave them above in the create_table :posts part?

EG which is correct:

 def up
    create_table :posts do |t|
      #put it here as t.integer :user_id?
    end
    Post.create_translation_table! :title => string, :text => :text #user_id dec here?
 end

Thanks!

役に立ちましたか?

解決

Quick answer: yes, you treat untranslated attributes just like you would attributes in any other activerecord model, so:

create_table :posts do |t|
  t.integer :user_id
end

is correct.

What create_translation_table is doing is creating a separate table called post_translations, where it will store individual translations of translated attributes along with the locale of the specific translation and the id of the parent record in the posts table.

If you look at schema.rb after you run the migration, you will see two tables, one with the user_id (and timestamps, always required):

create_table "posts", :force => true do |t|
  t.integer  "user_id"
  t.datetime "created_at",                 :null => false
  t.datetime "updated_at",                 :null => false
end

and another table for the translations of translated attributes, which is created by your call to create_translation_table in the migration:

create_table "post_translations", :force => true do |t|
  t.integer  "post_id"
  t.string   "locale"
  t.string   "title"
  # any other translated attributes would appear here
  t.datetime "created_at",  :null => false
  t.datetime "updated_at",  :null => false
end

You might ask, why does globalize3 create a separate table at all? Why not just put them in the same table as the parent record (in the form, say title_en, title_es etc.)? There are other translation gems that do this, e.g. traco. The catch though is that if you put the translations in the parent record, then you have to specify beforehand what locales you will be supporting, because you need to create columns for the attribute in each locale. If you add new locales, you then have to migrate your database to support them.

With the globalize3 solution, on the other hand, you don't have to decide on what locales you will support beforehand, because each translated record in the translation table has a locale attached to it -- nowhere do you "hard-code" the supported locales. This is quite an elegant way to deal with the issue and underlies the popularity of globalize3, but it can be a bit confusing at the beginning because the gem has to do some trickery to make it look like the attributes are attached to the model (Post) whereas they are actually attached to another class, Post::Translation.

Anyway that was more than you asked for, but useful stuff to know.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top