Caching users

4 views
Skip to first unread message

Swards

unread,
Nov 3, 2009, 1:47:44 PM11/3/09
to declarative_authorization
I have a model where I am caching the id's of the privileged users in
a column. It's a serialized array of ids. How would I set up the
authorization rules to check this column for access? I could change
the data format in the column if that would be better - it is used
only for declarative auth.

I tried the following:

has_permission_on [:my_object], :to => :manage do
if_attribute :effective_managers => contains {user.id}
end

effective_managers is my column of user_ids.

This is generating sql like this:

SELECT * FROM `my_objects` WHERE (`my_objects`.`effective_managers` =
8); # 8 is the id of the current_user

I'm not sure what the best way would be to structure the data and
write the authorization rules.

Do you have suggestions for this approach?

Thanks

- Mark

Steffen Bartsch

unread,
Nov 4, 2009, 7:08:03 AM11/4/09
to declarative_...@googlegroups.com
Am Dienstag, 3. November 2009 schrieb Swards:
> SELECT * FROM `my_objects` WHERE (`my_objects`.`effective_managers` =
> 8); # 8 is the id of the current_user
>
> I'm not sure what the best way would be to structure the data and
> write the authorization rules.
>
> Do you have suggestions for this approach?

The most straight-forward way is to have a has_many :through association
between my_objects and users. Then, you wouldn't even need to change the
current rule.

Steffen

Swards

unread,
Nov 5, 2009, 1:49:50 AM11/5/09
to declarative_authorization
I have a data model that requires different roles on different
objects.

I was storing the object/user/role relationship in a memberships
model. The object is polymorphic. The role was basically an
enumeration of strings (owner, manager, member, etc).

The Migration:

create_table :relationships do |t|
t.references :user, :role
t.references :context, :polymorphic => true
t.timestamps
end

Relationship < ActiveRecord:Base
belongs_to :context, :polymorphic => true
belongs_to :user
belongs_to :role

Business
has_many :memberships, :class_name => 'Relationship', :conditions =>
{ :role => 'member' }
has_many :members, :through => :memberships, :source => :user

This did not work - the SQL generated for the join was barfing due to
the automated way rails generates join table name aliases. It
wouldn't recognize the 'role' column.

SO, then I tried Single Table Inheritance.

I created a Relationship class that had subclasses for Membership,
Ownership, etc.

When I tried to set up the Business

Business
has_many :memberships
has_many :members, :through => :memberships, :source => :user
has_many :ownerships
has_many :owners, :through => :ownerships, :source => :user

The sql generated by declarative auth to determine privileges ignored
the single table inheritance and returned the same list for members as
owners. A user with any relationship had every relationship. Just
using active record, the list of business.owners and business.managers
was correct. Not sure why declarative auth was unable to use this.

Back to the drawing board...

I ultimately created multiple tables (one for each role) and a module
to define 'Relationship'.

module Relationship

def self.included(base)
base.class_eval do
belongs_to :context, :polymorphic => true
belongs_to :user

validates_uniqueness_of :user_id, :scope =>
[:context_id, :context_type]
end
end

end

And for Membership, Ownership, etc. they are setup like so...

class Membership< ActiveRecord::Base
include Relationship

end

I like this as it is really fast for declarative auth to get the list
of users as you suggest, the downside of course - I have multiple
tables that are all pretty similar. Would rather use the STI.

- Mark
Reply all
Reply to author
Forward
0 new messages