diff --git a/lib/generators/rolify/templates/initializer.rb b/lib/generators/rolify/templates/initializer.rb index 0d25416d..c156f1d7 100644 --- a/lib/generators/rolify/templates/initializer.rb +++ b/lib/generators/rolify/templates/initializer.rb @@ -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 diff --git a/lib/rolify/adapters/active_record/resource_adapter.rb b/lib/rolify/adapters/active_record/resource_adapter.rb index 26487c63..c14d4aa7 100644 --- a/lib/rolify/adapters/active_record/resource_adapter.rb +++ b/lib/rolify/adapters/active_record/resource_adapter.rb @@ -19,7 +19,7 @@ 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 @@ -27,7 +27,7 @@ def resources_find(roles_table, relation, role_name) 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) diff --git a/lib/rolify/adapters/active_record/role_adapter.rb b/lib/rolify/adapters/active_record/role_adapter.rb index 4c670fdc..9ea2b30a 100644 --- a/lib/rolify/adapters/active_record/role_adapter.rb +++ b/lib/rolify/adapters/active_record/role_adapter.rb @@ -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 @@ -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| @@ -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) @@ -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 diff --git a/lib/rolify/adapters/active_record/scopes.rb b/lib/rolify/adapters/active_record/scopes.rb index 4ec81e57..b57604ee 100644 --- a/lib/rolify/adapters/active_record/scopes.rb +++ b/lib/rolify/adapters/active_record/scopes.rb @@ -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 \ No newline at end of file +end diff --git a/lib/rolify/configure.rb b/lib/rolify/configure.rb index 96c00c74..191a844f 100644 --- a/lib/rolify/configure.rb +++ b/lib/rolify/configure.rb @@ -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 diff --git a/lib/rolify/role.rb b/lib/rolify/role.rb index 8e6f4367..7b94dd9f 100644 --- a/lib/rolify/role.rb +++ b/lib/rolify/role.rb @@ -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