% 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
セコメントをする