TodoLIst: User の多言語対応2007年01月05日 10時49分26秒

まず、多言語対応のために、言語表を作る。ついでに他のテーブルも変更。

% cat multilingual.mysql 
USE todos;
DROP TABLE IF EXISTS languages;
CREATE TABLE `languages`
(
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(40),
  PRIMARY KEY(`id`)
);
INSERT INTO languages VALUES(NULL, 'English');
INSERT INTO languages VALUES(NULL, 'Japanese');

ALTER TABLE todos ADD language_id INT;
ALTER TABLE users ADD language_id INT;
ALTER TABLE todos ADD primary_id INT;
% cat multilingual.mysql | mysql

そして、Language モデルを作る。


% ruby script/generate model Language
      exists  app/models/
      exists  test/unit/
      exists  test/fixtures/
      create  app/models/language.rb
      create  test/unit/language_test.rb
      create  test/fixtures/languages.yml
      exists  db/migrate
      create  db/migrate/003_create_languages.rb

次に、ユーザ (User) に言語設定を加える。

User モデルは login_engine からも参照されている。


% cvs diff config/environment.rb
diff -u -r1.3 environment.rb
--- config/environment.rb       26 Dec 2006 04:10:32 -0000      1.3
+++ config/environment.rb       3 Jan 2007 04:34:47 -0000
@@ -56,7 +56,7 @@
   config :user_email_notification, false
   config :changeable_fields,
     [ 'firstname', 'lastname', 'login', 'email',
-    'organization_id', 'title', 'phone', 'fax', 'address'
+    'organization_id', 'title', 'phone', 'fax', 'address', 'language_id'
     ]
 end

と、language_id を追加する。これで、edit_user などのアクションが自動的に対応される。

次に User モデルと Language モデルの間に一対多の関連を付ける。


% cat app/models/language.rb
class Language < ActiveRecord::Base
  has_many :users
end
% cvs diff app/models/user.rb
--- app/models/user.rb  1 Jan 2007 06:23:42 -0000       1.4
+++ app/models/user.rb  2 Jan 2007 08:49:34 -0000
@@ -29,6 +29,7 @@
   #cattr_accessor :current_user
 
   belongs_to :organization
+  belongs_to :language
 
   has_many :created_todos, :foreign_key => "creator_id", :class_name => "Todo"
   has_many :assigned_todos, :foreign_key => "assignee_id", :class_name => "Todo"

そして、app/views/user 以下にある、_edit.rhtml と list.rhtml に変更を加えれば、ユーザ (User) にデフォルトの言語を設定できるようになる。これは以前にやった、所属組織 (Organization) への対応といっしょだ。


% cvs diff app/views/user
--- app/views/user/_edit.rhtml  27 Dec 2006 03:22:38 -0000      1.6
+++ app/views/user/_edit.rhtml  2 Jan 2007 08:43:11 -0000
@@ -27,6 +27,17 @@
    </td>
    </tr>
 
+   <tr class="two_columns">
+   <td class="prompt"><lable>Language:</label></td>
+   <td class="value">
+    <%= select :user, :language_id,
+     Language.find(:all).map {|l| [ l.name, l.id ]},
+     { :include_blank => true },
+     {}
+     %>
+   </td>
+   </tr>
+
     <% if submit %>
       <%= form_input :submit_button, (user.new_record? ? 'Signup' : 'Change 
Settings'), :class => 'two_columns' %>
     <% end %>
--- app/views/user/list.rhtml   26 Dec 2006 04:10:32 -0000      1.3
+++ app/views/user/list.rhtml   2 Jan 2007 08:44:11 -0000
@@ -6,6 +6,7 @@
     <th><%= column.human_name %></th>
 <% end %>
     <th>Organization</th>
+    <th>Language</th>
     <th>Actions</th>
   </tr>
 
@@ -15,6 +16,7 @@
     <td><%=h user.send(column.name) %></td>
   <% end %>
     <td><%= Organization.find(user.organization_id).name if user.organ
ization_id %></td>
+    <td><%= Language.find(user.language_id).name if user.language_id %
></td>
     <td>
       <ul class="actions">
         <%= link_if_authorized 'Show', {:action => 'show', :id => user
}, :wrap_in => "li" %>

なお、app/environment.rb で変更可能かを設定できるので、User コントローラを触る必要はない。

前回次回