Rails
Access Control List Example

Database schema (Postgre SQL)

CREATE TABLE users (
    id serial NOT NULL,
    nick character varying NOT NULL,
    name character varying,
    "password" character varying NOT NULL,
    modified timestamp with time zone 
        DEFAULT ('now'::text)::timestamp(6) with time zone NOT NULL,
    created timestamp with time zone 
        DEFAULT ('now'::text)::timestamp(6) with time zone NOT NULL,
    "access" timestamp with time zone
);
ALTER TABLE ONLY users
    ADD CONSTRAINT user_pkey PRIMARY KEY (id);
CREATE TABLE roles (
    id serial NOT NULL,
    name character varying NOT NULL,
    info character varying
);
ALTER TABLE ONLY roles
    ADD CONSTRAINT role_pkey PRIMARY KEY (id);
CREATE TABLE permissions (
    id serial NOT NULL,
    name character varying NOT NULL,
    info character varying
);
ALTER TABLE ONLY permissions
    ADD CONSTRAINT permission_pkey PRIMARY KEY (id);
CREATE TABLE users_roles (
    user_id integer NOT NULL,
    role_id integer NOT NULL
);
CREATE INDEX ur_map_idx ON user_roles USING btree (user_id, role_id);
ALTER TABLE ONLY user_roles
    ADD CONSTRAINT "$1" FOREIGN KEY (user_id) REFERENCES users(id) 
        ON UPDATE CASCADE ON DELETE CASCADE;
ALTER TABLE ONLY user_roles
    ADD CONSTRAINT "$2" FOREIGN KEY (role_id) REFERENCES roles(id) 
        ON UPDATE CASCADE ON DELETE CASCADE;
CREATE TABLE permissions_roles (
    role_id integer NOT NULL,
    permission_id integer NOT NULL
);
CREATE INDEX pr_map_idx ON permissions_roles USING btree (role_id, permission_id);
ALTER TABLE ONLY permissions_roles
    ADD CONSTRAINT "$1" FOREIGN KEY (role_id) REFERENCES roles(id) 
        ON UPDATE CASCADE ON DELETE CASCADE;
ALTER TABLE ONLY permissions_roles
    ADD CONSTRAINT "$2" FOREIGN KEY (permission_id) REFERENCES permissions(id) 
        ON UPDATE CASCADE ON DELETE CASCADE;

Model code

require 'active_record'
class Permission < ActiveRecord::Base
  has_and_belongs_to_many :roles
end
class Role < ActiveRecord::Base
  has_and_belongs_to_many :permissions
  has_and_belongs_to_many :users
end
class User < ActiveRecord::Base
  has_and_belongs_to_many :roles
end

Example Usage

Get the user associated with id #1:

user = User.find(1)

Get the roles associated with this user:

roles = user.roles

Get the permissions for the first role associated with the user:

perms = roles[0].permissions

Add role #2 to the user:

role = Role.find(2)
user.add_roles(role)
user.save

Add a few more permissions to role #2:

role.add_permissions(Permission.find(2), Permission.find(3))
role.save

Remove one of the permissions again:

role.remove_permissions(Permission.find(3))
role.save

category:Example