Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow to select the primary key of the resource (instead of id, which is the default) #494

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
3 changes: 3 additions & 0 deletions lib/generators/rolify/templates/initializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@

# Configuration to remove roles from database once the last resource is removed. Default is: true
# config.remove_role_if_empty = false

# Configuration to the primary key of the resource. Default is: "id"
# config.resource_primary_key = "id"
end
4 changes: 2 additions & 2 deletions lib/rolify/adapters/active_record/resource_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ def resources_find(roles_table, relation, role_name)
end

resources = relation.joins("INNER JOIN #{quote_table(roles_table)} ON #{quote_table(roles_table)}.resource_type IN (#{relations}) AND
(#{quote_table(roles_table)}.resource_id IS NULL OR #{quote_table(roles_table)}.resource_id = #{quote_table(relation.table_name)}.#{quote_column(relation.primary_key)})")
(#{quote_table(roles_table)}.resource_id IS NULL OR #{quote_table(roles_table)}.resource_id = #{quote_table(relation.table_name)}.#{quote_column(relation.primary_key)} #{"OR #{quote_table(roles_table)}.resource_id = #{quote_table(relation.table_name)}.#{Rolify.resource_primary_key}" if relation.table_name.classify.constantize.column_names.include? Rolify.resource_primary_key} )")
resources = resources.where("#{quote_table(roles_table)}.name IN (?) AND #{quote_table(roles_table)}.resource_type IN (?)", Array(role_name), klasses)
resources = resources.select("#{quote_table(relation.table_name)}.*")
resources
end

def in(relation, user, role_names)
roles = user.roles.where(:name => role_names).select("#{quote_table(role_class.table_name)}.#{quote_column(role_class.primary_key)}").to_a
relation.where("#{quote_table(role_class.table_name)}.#{quote_column(role_class.primary_key)} IN (?) AND ((#{quote_table(role_class.table_name)}.resource_id = #{quote_table(relation.table_name)}.#{quote_column(relation.primary_key)}) OR (#{quote_table(role_class.table_name)}.resource_id IS NULL))", roles)
relation.where("#{quote_table(role_class.table_name)}.#{quote_column(role_class.primary_key)} IN (?) AND ((#{quote_table(role_class.table_name)}.resource_id = #{quote_table(relation.table_name)}.#{quote_column(relation.primary_key)}) #{"OR (#{quote_table(role_class.table_name)}.resource_id = #{quote_table(relation.table_name)}.#{Rolify.resource_primary_key})" if relation.table_name.classify.constantize.column_names.include? Rolify.resource_primary_key} OR (#{quote_table(role_class.table_name)}.resource_id IS NULL))", roles)
end

def applied_roles(relation, children)
Expand Down
10 changes: 5 additions & 5 deletions lib/rolify/adapters/active_record/role_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ def where_strict(relation, args)
resource = if args[:resource].is_a?(Class)
{class: args[:resource].to_s, id: nil}
else
{class: args[:resource].class.name, id: args[:resource].id}
{class: args[:resource].class.name, id: args[:resource].send(Rolify.resource_primary_key)}
end

relation.where(:name => args[:name], :resource_type => resource[:class], :resource_id => resource[:id])
end

def find_cached(relation, args)
resource_id = (args[:resource].nil? || args[:resource].is_a?(Class) || args[:resource] == :any) ? nil : args[:resource].id
resource_id = (args[:resource].nil? || args[:resource].is_a?(Class) || args[:resource] == :any) ? nil : args[:resource].send(Rolify.resource_primary_key)
resource_type = args[:resource].is_a?(Class) ? args[:resource].to_s : args[:resource].class.name

return relation.find_all { |role| role.name == args[:name].to_s } if args[:resource] == :any
Expand All @@ -33,7 +33,7 @@ def find_cached(relation, args)
end

def find_cached_strict(relation, args)
resource_id = (args[:resource].nil? || args[:resource].is_a?(Class)) ? nil : args[:resource].id
resource_id = (args[:resource].nil? || args[:resource].is_a?(Class)) ? nil : args[:resource].send(Rolify.resource_primary_key)
resource_type = args[:resource].is_a?(Class) ? args[:resource].to_s : args[:resource].class.name

relation.find_all do |role|
Expand All @@ -52,7 +52,7 @@ def add(relation, role)
def remove(relation, role_name, resource = nil)
cond = { :name => role_name }
cond[:resource_type] = (resource.is_a?(Class) ? resource.to_s : resource.class.name) if resource
cond[:resource_id] = resource.id if resource && !resource.is_a?(Class)
cond[:resource_id] = resource.send(Rolify.resource_primary_key) if resource && !resource.is_a?(Class)
roles = relation.roles.where(cond)
if roles
relation.roles.delete(roles)
Expand Down Expand Up @@ -113,7 +113,7 @@ def build_query(role, resource = nil)
values << role << (resource.is_a?(Class) ? resource.to_s : resource.class.name)
if !resource.is_a? Class
query += " OR ((#{role_table}.name = ?) AND (#{role_table}.resource_type = ?) AND (#{role_table}.resource_id = ?))"
values << role << resource.class.name << resource.id
values << role << resource.class.name << resource.send(Rolify.resource_primary_key)
end
query += ")"
end
Expand Down
4 changes: 2 additions & 2 deletions lib/rolify/adapters/active_record/scopes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ def instance_scoped(resource_type = nil)
if resource_type.is_a? Class
where_conditions = [ "resource_type = ? AND resource_id IS NOT NULL", resource_type.name ]
else
where_conditions = [ "resource_type = ? AND resource_id = ?", resource_type.class.name, resource_type.id ]
where_conditions = [ "resource_type = ? AND resource_id = ?", resource_type.class.name, resource_type.send(Rolify.resource_primary_key) ]
end
end
where(where_conditions)
end
end
end
end
end
9 changes: 9 additions & 0 deletions lib/rolify/configure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,21 @@ module Configure
@@dynamic_shortcuts = false
@@orm = "active_record"
@@remove_role_if_empty = true
@@resource_primary_key = "id"

def configure(*role_cnames)
return if !sanity_check(role_cnames)
yield self if block_given?
end

def resource_primary_key
@@resource_primary_key
end

def resource_primary_key=(resource_primary_key_name)
@@resource_primary_key = resource_primary_key_name
end

def dynamic_shortcuts
@@dynamic_shortcuts
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rolify/role.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def self.included(base)
def add_role(role_name, resource = nil)
role = self.class.adapter.find_or_create_by(role_name.to_s,
(resource.is_a?(Class) ? resource.to_s : resource.class.name if resource),
(resource.id if resource && !resource.is_a?(Class)))
(resource.send(Rolify.resource_primary_key) if resource && !resource.is_a?(Class)))

if !roles.include?(role)
self.class.define_dynamic_method(role_name, resource) if Rolify.dynamic_shortcuts
Expand Down