photomix/app/models/role_membership.rb

36 lines
1.4 KiB
Ruby

class RoleMembership < ActiveRecord::Base
belongs_to :user
belongs_to :role
belongs_to :roleable, :polymorphic => true
validates_presence_of :roleable_id, :roleable_type, :role_id
validates_uniqueness_of :role_id, :scope => [:roleable_id, :roleable_type]
validates_numericality_of :roleable_id, :role_id
validates_format_of :roleable_type, :with => /^[A-Z]{1}[a-z0-9]+([A-Z]{1}[a-z0-9]+)*$/
validate :role_does_not_belong_to_itself_in_a_loop
protected
def role_does_not_belong_to_itself_in_a_loop
if roleable_type == "Role"
if role_id == roleable_id
errors.add_to_base("A role cannot belong to itself.")
else
if belongs_to_itself_through_other?(roleable_id, role_id)
errors.add_to_base("A role cannot belong to a role which belongs to it.")
end
end
end
end
def belongs_to_itself_through_other?(original_roleable_id, current_role_id)
if self.class.find(:first, :select => "id", :conditions => ["roleable_id=? AND roleable_type='Role' AND role_id=?",current_role_id,original_roleable_id])
return true
else
memberships = self.class.find(:all, :select => "role_id", :conditions => ["roleable_id=? AND roleable_type='Role'",current_role_id])
if memberships.any? {|membership| belongs_to_itself_through_other?(original_roleable_id,membership.role_id)}
return true
end
end
return false
end
end