2013-10-15 33 views
1

考虑以下模式:授权邀请用户通过数据库触发器

Table "public.users" 
     Column  |   Type   |       Modifiers 
----------------------+--------------------------+------------------------------------------------------------ 
uuid     | uuid      | not null default uuid_generate_v4() 
email    | character varying(254) | not null 
name     | text      | not null 
created_at   | timestamp with time zone | not null default now() 

Table "public.users_projects" 
    Column  |   Type   |     Modifiers 
-----------------+--------------------------+-------------------------------------------- 
project_uuid | uuid      | not null 
user_uuid  | uuid      | not null 
invitation_uuid | uuid      | 
membership_type | membership_type   | not null default 'member'::membership_type 
created_at  | timestamp with time zone | not null default now() 

Table "public.projects" 
    Column |   Type   |    Modifiers 
------------+--------------------------+------------------------------------- 
uuid  | uuid      | not null default uuid_generate_v4() 
name  | character varying(100) | not null 
created_at | timestamp with time zone | not null default now() 

Table "public.invitations" 
    Column  |   Type   |     Modifiers 
-----------------+--------------------------+-------------------------------------------- 
uuid   | uuid      | not null default uuid_generate_v4() 
email   | character varying(254) | not null 
target_type  | character varying(50) | not null 
target_uuid  | uuid      | not null 
membership_type | membership_type   | not null default 'member'::membership_type 
token   | character varying(32) | not null default md5((random())::text) 
creator_uuid | uuid      | not null 

也有一个枚举类型CREATE TYPE membership_type AS ENUM ('guest', 'member', 'manager', 'owner');

我想知道如果我可以使用触发器来验证用户不能创建一个资源的邀请,至少没有连接表上的成员类型manager

我的主要问题是:

  • 我可以将该行插入“之前”使用触发器,CREATE TRIGGER check_authorisation BEFORE INSERT OR UPDATE ON invitations FOR EACH ROW EXECUTE PROCEDURE check_authorisation();
  • 我多少信息可以给回一条错误消息,因为对刚刚失败,因为数据库连接断开等
  • 这是一个理智的方法吗?作为一个Web应用程序开发人员,我习惯于在应用程序代码中检查这个环境,但是我正在处理将由两个应用程序共享的数据库(Golang和Ruby)
  • 我可以实现REFERENCES在多态字段(target_type,target_uuid)以某种方式?

回答

0

我可以用一个触发行插入 “之前”,CREATE TRIGGER check_authorisation BEFORE插入或更新为每个ROW EXECUTE PROCEDURE check_authorisation邀请();

使其成为(之后)约束触发器,并在适当时引发异常。

更一般地说,在触发器传播副作用和约束触发器以验证完整性之后,在需要时使用触发器之前修改传入数据。

我多少信息可以给回一条错误消息,因为对刚刚失败,因为数据库连接下来,等

只要你想提高你的异常时发送太多。

这是一种理智的方法吗?作为一个Web应用程序开发人员,我习惯于在应用程序代码中检查这个环境,但我正在处理将由两个应用程序(Golang和Ruby)共享的数据库。

它可以如果做得对,那么理智就没有问题,但是,在授权方面,正确管理所有的怪异案例基本上是不可能的,所以这种类型的逻辑通常更好地位于数据库之外。

案例:经理的秘书更换(原来的产假)会发生什么?

能否以某种方式在多态字段(target_type,target_uuid)上实现REFERENCES?

你可以用后触发。但是,根据你在做什么,考虑用单独的字段,外键和检查约束对它进行规范化,以确保它们是互斥的。管理起来往往比管理更简单/清洁,而最终还是等于手动重写外键逻辑。