ユーザがログインをして、http://localhost:3000/todo/list にアクセスするので、そのユーザが属している団体 (organization) に対しての公開制限をかける必要がある。http://localhost:3000/todo/show/1 にアクセスする時の id = 1 は todo の id だ。user の id はどこから取って来られるのだろうか。
user_engine のコードを見ていたときに @session に頻繁にアクセスしているのに気が付いた。 そこで、<%= @session.inspect %>
を list.rhtml に追加して、その値を調べてみる。随分大量の変数が保存されていて、どのように何にアクセス出来るのかが分かりづらかった。しかし、最終的には @session[:user][:organization_id].inspect にて所属組織 (Organization) を取得できた。
違うアカウントを作り、他の団体 (Organization) に所属させてアクセスしてみると正しく制限が掛けられているのが確認できた。
しかし、todos テーブルの二つ目のレコードの「enter todos」を編集しようとすると、そのようなレコードは存在しないとエラーが出る。転送先の URL を見ると http://localhost:3000/todo/edit/4 となっている。
mysql> select * from todos inner join todo_organization_permissions
on todo_organization_permissions.todo_id = todos.id where published = 1 AND
organization_id = 1;
+----+------------------+------+----+---------+-----------------+-----------+
| id | description | done | id | todo_id | organization_id | published |
+----+------------------+------+----+---------+-----------------+-----------+
| 1 | create todo list | 0 | 1 | 1 | 1 | 1 |
| 2 | enter todos | 0 | 4 | 2 | 1 | 1 |
+----+------------------+------+----+---------+-----------------+-----------+
2 rows in set (0.01 sec)
id のコラムが二つ出来ていて、後者の id が 4 になっている。恐らく rails がどちらが期待されている id かを見分けがついていないのだろう。そこで、todos のテーブルと同一のテーブルを作って、回避する事にした。
新しい、app/controllers/todo_controller.rb の list 関数である。
def list
@todo_pages, @todos = paginate(:todos,
:select =>
Todo.columns.map{ |column| "todos." + column.name.to_s() }.join(", "),
:joins => "LEFT JOIN todo_organization_permissions" +
" on todo_organization_permissions.todo_id = todos.id where " +
"published = 1 AND organization_id = " +
session[:user][:organization_id].to_s(),
:per_page => 10)
end
:select
を用いて、明示的に join されたテーブルを指定するようにした。 実験してみる。まずは、uyota アカウントから隠されている Todo 項目を作る。
mysql> INSERT INTO todos VALUE ( NULL, 'Hide from uyota.', 0);
Query OK, 1 row affected (0.00 sec)
mysql> select * from todos;
+----+------------------+------+
| id | description | done |
+----+------------------+------+
| 1 | Create todo list | 0 |
| 2 | Enter todos | 0 |
| 3 | Hide from uyota. | 0 |
+----+------------------+------+
3 rows in set (0.00 sec)
http://localhost:3000/todo/list にアクセス。
Listing todos
Description | Done | |||
---|---|---|---|---|
create todo list | 0 | Show | Edit | Destroy |
Enter todos | 0 | Show | Edit | Destroy |
セコメントをする