TodoList: 多国語対応 Todo 詳細の表示2007年01月10日 12時04分27秒

まずは、テスト用のデータを入れる。これが無いと、正しく表示されているのかわからない。

% cat multilingual2.mysql
USE todos;
DROP TABLE IF EXISTS `descriptions`;
CREATE TABLE `descriptions`
(
  `id` INT NOT NULL AUTO_INCREMENT,
  `todo_id` INT NOT NULL,
  `description` VARCHAR(100) NOT NULL,
  `language_id` INT NOT NULL,
  PRIMARY KEY(`id`)
);
ALTER TABLE todos DROP language_id;
ALTER TABLE todos CHANGE description title VARCHAR(100) NOT NULL;

INSERT INTO descriptions VALUES(NULL, 1, 'English Description', 1);
INSERT INTO descriptions VALUES(NULL, 1, 'Japanese Description', 2);
% grep INSERT | mysql todos

app/views/todo/edit.rhtml と app/views/todo/show.rhtml を変更。edit.rhtml で、言語を変更できるようにしようかと思ったが、:selected => value が正しく動作しないので、今は変更を見送ることにした。まだ、この部分は実験用なので、_add2.rhtml が名前に反して、詳細 (Description) の追加ではなく、表示のみをする。


% cvs diff app/views/todo
--- edit.rhtml  20 Dec 2006 03:55:08 -0000      1.2
+++ edit.rhtml  9 Jan 2007 03:56:45 -0000
@@ -5,6 +5,13 @@
   <%= submit_tag 'Edit' %>
 <%= end_form_tag %>
 
+<%= start_form_tag :action => 'edit', :id => @todo %>
+  <%= render :partial => 'add' %>
+  <%= submit_tag 'Add' %>
+<%= end_form_tag %>
+
+  <%= render :partial => 'add2', :collection => @todo.descriptions %&g
t;
+
 <%= render :partial => 'published' %>
 
 <%= link_to 'Show', :action => 'show', :id => @todo %> |
--- show.rhtml  20 Dec 2006 03:55:08 -0000      1.4
+++ show.rhtml  5 Jan 2007 03:23:36 -0000
@@ -4,6 +4,8 @@
 </p>
 <% end %>
 
+<%= render :partial => 'add2', :collection => @todo.descriptions %>
+
 <%= render :partial => 'published' %>
 
 <%= link_to 'Edit', :action => 'edit', :id => @todo %> |

edit.rhtml 内で新しい説明 (Description) を追加するために _add.rhtml を呼び出す。

% cat _add.rhtml
<%= error_messages_for 'description' %>

<!--[form:description]-->
<p><label for="description_description">Language</label>
  <label>Description</label><br/>
    <%= select :description, :language_id,
     Language.find(:all).map {|l| [ l.name, l.id ]},
     {},
     {}
     %>
<%= text_field 'description', 'description'  %>
</p>

<!--[eoform:description]-->

まあ、_add.rhtml は今までで見慣れてきたコードだ。

render :collection を試すのは初めてだ。:collection を使うと自動的に collection に対しループで回されるらしい。つまり、一つのレコードを表示する partial rhtml を書いて、:collection を与えると、それで複数のレコードの対応となるわけだ。とても、便利だ。

どこにも記述されていなかったのだが、_add2.rhtml 内で、collection の各要素は add2 に割り当てられるらしい。すなわち、下線と rhtml の拡張子を除いたファイル名だ。@ を付けて @add2 とやったら、予期されていない nil だと言われてエラーになった。


% cat _add2.rhtml
<%= error_messages_for 'description' %>

<tr id="description_<%= add2.id %>" >

  <!--[form:description]-->
  <p><label for="description_description">Description (
  <%= Language.find(add2.language_id).name %>
  ):
  </label>
  <%= text_field 'description', 'description',
    :name => "description[" + add2.id.to_s() + "][description]",
    :value => add2.description %>
  <%= hidden_field 'description', 'language_id', :value => add2.language_id %>
  </p>

  <!--[eoform:description]-->

</tr>

これで、Todo の詳細 (Description) を表示できるようにはなった。随分と手を抜いた表示にはなっている。また後で、編集できるようにしたいので、上のコードにはそれに備えて実験用のコードを残したままだ。

app/controllers/todo_controller.rb も変更しなければ。todo/edit 内で、詳細 (Description) を追加できるようにしてあるので、todo_contoller.rb の edit 関数内で処理できる。


% cvs diff app/controllers/todo_controller.rb
--- app/controllers/todo_controller.rb  27 Dec 2006 03:27:52 -0000      1.12
+++ app/controllers/todo_controller.rb  5 Jan 2007 03:38:14 -0000
@@ -50,6 +50,8 @@
   def edit
     published()
     @todo = Todo.find(params[:id])
+    desc = Description.new(params[:description])
+    @todo.descriptions << desc if desc.description.length() != 0
   end
 
   def update

前回次回