TodoList: 作成者を記録2006年12月31日 11時45分56秒

以前から作りたいと思っていた Todo の作成者 (Creator) を追加したい。これは、todos テーブルと、users テーブルの一対多の関係となる。そして、Todo なので、担当者 (Assignee) も付けられる様にする。こちらも同様の一対多だ。

つまり、Rails の一対多の関係を単純には使えない。has_many と belongs_to にて外部キーを指定する必要がある。app/models/todo.rb と app/models/user.rb に以下の変更を加えた。


% cvs diff app/models
--- app/models/todo.rb  26 Dec 2006 04:11:12 -0000      1.2
+++ app/models/todo.rb  26 Dec 2006 08:54:11 -0000
@@ -1,4 +1,7 @@
 class Todo < ActiveRecord::Base
-  has_many :todo_organiation_permissions
+  has_many :todo_organization_permissions
   has_many :organizations, :through=>:todo_organization_permissions
+
+  belongs_to :creator, :foreign_key => "creator_id", :class_name => "User
"
+  belongs_to :assignee, :foreign_key => "assignee_id", :class_name => "Us
er"
 end
--- app/models/user.rb  6 Dec 2006 07:14:51 -0000       1.2
+++ app/models/user.rb  26 Dec 2006 08:14:03 -0000
@@ -27,6 +27,10 @@
 # module, and is further extended by UserEngine::AuthorizedUser.
 class User < ActiveRecord::Base
   belongs_to :organization
+
+  has_many :created_todos, :foreign_key => "creator_id", :class_name => "
Todo"
+  has_many :assigned_todos, :foreign_key => "assignee_id", :class_name =>
 "Todo"
+
   include LoginEngine::AuthenticatedUser
   include UserEngine::AuthorizedUser

todos テーブルに新しい項目を追加する。


% cat owners.mysql
USE todos;
ALTER TABLE todos ADD creator_id INT;
ALTER TABLE todos ADD assignee_id INT;
% cat owners.mysql | mysql

次に todo/new を作成者 (Creator) を割り当てるように変更する。http://localhost:3000/todo/new の入力は create 関数に渡される。作成者は変える必要がないので、新規に作られるときのみ割り当てる。作成者の id は user_engine のおかげで @session から取り出せる。


% cvs diff app/controllers/todo_controller.rb
--- app/controllers/todo_controller.rb  26 Dec 2006 05:34:30 -0000      1.11
+++ app/controllers/todo_controller.rb  26 Dec 2006 08:51:08 -0000
@@ -37,6 +38,7 @@
 
   def create
     @todo = Todo.new(params[:todo])
+    @todo.creator_id = @session[:user][:id]
     if @todo.save
       flash[:notice] = 'Todo was successfully created.'
       redirect_to :action => 'list

http://localhost:3000/todo/new にアクセスして、「Test TodoList」を入力した。しかし、http://localhost:3000/todo/list にアクセスしても今入れたばかりの Todo レコードがない。todo/list も変更する必要がある。昔の条件に加えて、自信の id が creator_id であれば表示する。

まずは、SQL を自分で試す。


mysql> SELECT * FROM todos LEFT JOIN todo_organization_permissions
 ON todo_organization_permissions.todo_id = todos.id
 WHERE (published = 1 AND organization_id = 1) OR creator_id = 1;
+----+------------------+------+------------+-------------+------+---------+-----------------+-----------+
| id | description      | done | creator_id | assignee_id | id   | todo_id | organization_id | published |
+----+------------------+------+------------+-------------+------+---------+-----------------+-----------+
|  1 | Create todo list |    0 |       NULL |        NULL |    1 |       1 |               1 |         1 | 
|  2 | Enter todos      |    0 |       NULL |        NULL |    4 |       2 |               1 |         1 | 
|  4 | Test TodoList    |    0 |          1 |        NULL | NULL |    NULL |            NULL |      NULL | 
+----+------------------+------+------------+-------------+------+---------+-----------------+-----------+
3 rows in set (0.01 sec)

うまくいったようだ。

今度はこれと等価な SQL を todo_controller.rb から作ればよい。


% cvs diff app/controllers/todo_controller.rb
--- app/controllers/todo_controller.rb  26 Dec 2006 05:34:30 -0000      1.11
+++ app/controllers/todo_controller.rb  26 Dec 2006 08:51:08 -0000
@@ -21,8 +21,9 @@
       #  "published = 1 AND organization_id = " +
       #  session[:user][:organization_id].to_s(),
       :include => :todo_organization_permissions,
-        :joins => ["WHERE published = 1 AND organization_id = " +
-         session[:user][:organization_id].to_s()],
+        :joins => ["WHERE (published = 1 AND " +
+         "organization_id = " + session[:user][:organization_id].to_s() + ")" +
+         " OR creator_id = " + session[:user][:id].to_s()],
       :per_page => 10)
   end

これで、所属団体 (Organization) に関係なく自分の作った Todo は見られる様になった。

前回次回

コメント

コメントをどうぞ

※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。

※なお、送られたコメントはブログの管理者が確認するまで公開されません。

名前:
メールアドレス:
URL:
コメント:

トラックバック

このエントリのトラックバックURL: http://uyota.asablo.jp/blog/2006/12/31/1083033/tb

※なお、送られたトラックバックはブログの管理者が確認するまで公開されません。