8 Commits
1.3.0 ... 1.3.3

Author SHA1 Message Date
Ryan Bates
a10a38c82f releasing version 1.3.3 2010-08-20 16:27:25 -07:00
Ryan Bates
caed4fcee5 use RSpec namespace for matcher - closes #119 2010-08-18 16:22:43 -07:00
Ryan Bates
e893e12260 fixing broken spec and minor improvements to tableized_conditions method 2010-08-18 16:04:08 -07:00
McClain Looney
3d7742ea43 fix for bug 123 2010-08-17 09:33:11 -05:00
Ryan Bates
a566ea0f4f releasing version 1.3.2 which fixes slice error when passing custom resource name 2010-08-07 08:38:35 -07:00
Ryan Bates
333ddf1970 properly pass along resource name without slice error - closes #112 2010-08-07 08:33:31 -07:00
Ryan Bates
cd74267364 releasing version 1.3.1 with sanitize_sql fix 2010-08-06 23:28:51 -07:00
Ryan Bates
f8631dcc93 fixing error on protected sanitize_sql - closes #111 2010-08-06 23:24:04 -07:00
10 changed files with 78 additions and 37 deletions

View File

@@ -1,11 +1,27 @@
1.3.3 (August 20, 2010)
* Switching to Rspec namespace to remove deprecation warning in Rspec 2 - see issue #119
* Pluralize nested associations for conditions in accessible_by (thanks mlooney) - see issue #123
1.3.2 (August 7, 2010)
* Fixing slice error when passing in custom resource name - see issue #112
1.3.1 (August 6, 2010)
* Fixing protected sanitize_sql error - see issue #111
1.3.0 (August 6, 2010) 1.3.0 (August 6, 2010)
* Adding :find_by option to load_resource - see issue #19 * Adding :find_by option to load_resource - see issue #19
* Adding :singleton option to load_resource - see issue #93 * Adding :singleton option to load_resource - see issue #93
* Supporting multiple resources in :through option for polymorphic * Supporting multiple resources in :through option for polymorphic associations - see issue #73
associations - see issue #73
* Supporting Single Table Inheritance for "can" comparisons - see issue #55 * Supporting Single Table Inheritance for "can" comparisons - see issue #55

View File

@@ -1,6 +1,6 @@
Gem::Specification.new do |s| Gem::Specification.new do |s|
s.name = "cancan" s.name = "cancan"
s.version = "1.3.0" s.version = "1.3.3"
s.author = "Ryan Bates" s.author = "Ryan Bates"
s.email = "ryan@railscasts.com" s.email = "ryan@railscasts.com"
s.homepage = "http://github.com/ryanb/cancan" s.homepage = "http://github.com/ryanb/cancan"

View File

@@ -34,14 +34,14 @@ module CanCan
end end
end end
# Returns a hash of conditions, pluralizing the table names def tableized_conditions(conditions = @conditions)
def tableized_conditions conditions.inject({}) do |result_hash, (name, value)|
if @conditions if value.kind_of? Hash
@conditions.inject({}) do |tableized_conditions, (name, value)| name = name.to_s.tableize.to_sym
name = name.to_s.tableize.to_sym if value.kind_of? Hash value = tableized_conditions(value)
tableized_conditions[name] = value
tableized_conditions
end end
result_hash[name] = value
result_hash
end end
end end

View File

@@ -2,9 +2,11 @@ module CanCan
# Handle the load and authorization controller logic so we don't clutter up all controllers with non-interface methods. # Handle the load and authorization controller logic so we don't clutter up all controllers with non-interface methods.
# This class is used internally, so you do not need to call methods directly on it. # This class is used internally, so you do not need to call methods directly on it.
class ControllerResource # :nodoc: class ControllerResource # :nodoc:
def self.add_before_filter(controller_class, method, options = {}) def self.add_before_filter(controller_class, method, *args)
options = args.extract_options!
resource_name = args.first
controller_class.before_filter(options.slice(:only, :except)) do |controller| controller_class.before_filter(options.slice(:only, :except)) do |controller|
ControllerResource.new(controller, options.except(:only, :except)).send(method) ControllerResource.new(controller, resource_name, options.except(:only, :except)).send(method)
end end
end end

View File

@@ -1,4 +1,5 @@
Spec::Matchers.define :be_able_to do |*args| RSpec = Spec unless defined? RSpec # for RSpec 1 compatability
RSpec::Matchers.define :be_able_to do |*args|
match do |ability| match do |ability|
ability.can?(*args) ability.can?(*args)
end end

View File

@@ -71,7 +71,7 @@ module CanCan
end end
def sanitize_sql(conditions) def sanitize_sql(conditions)
@sanitizer.sanitize_sql(conditions) @sanitizer.send(:sanitize_sql, conditions)
end end
# Takes two hashes and does a deep merge. # Takes two hashes and does a deep merge.

View File

@@ -31,8 +31,8 @@ describe CanCan::ActiveRecordAdditions do
@ability.can :read, @model_class, :too => {:car => 1, :far => {:bar => 1}} @ability.can :read, @model_class, :too => {:car => 1, :far => {:bar => 1}}
condition_variants = [ condition_variants = [
'(toos.far.bar=1 AND toos.car=1) OR (foos.bar=1)', # faked sql sanitizer is stupid ;-) '(toos.fars.bar=1 AND toos.car=1) OR (foos.bar=1)', # faked sql sanitizer is stupid ;-)
'(toos.car=1 AND toos.far.bar=1) OR (foos.bar=1)' '(toos.car=1 AND toos.fars.bar=1) OR (foos.bar=1)'
] ]
joins_variants = [ joins_variants = [
[:foo, {:too => [:far]}], [:foo, {:too => [:far]}],

View File

@@ -31,6 +31,18 @@ describe CanCan::CanDefinition do
@can.associations_hash.should == {:foo => {:bar => {}}} @can.associations_hash.should == {:foo => {:bar => {}}}
end end
it "should tableize correctly for absurdly complex permissions" do
@conditions[:unit] = {:property=>{:landlord=>{:weasle_id=>560}}}
@conditions[:test] = 1
@can.tableized_conditions.should == {:units => {:properties => {:landlords=>{:weasle_id=>560}}}, :test => 1}
end
it "should tableize correctly for complex permissions" do
@conditions[:unit] = {:property=>{:landlord_id=>560}}
@conditions[:test] = 1
@can.tableized_conditions.should == {:units => {:properties => {:landlord_id=>560}}, :test => 1}
end
it "should return table names in conditions for association joins" do it "should return table names in conditions for association joins" do
@conditions[:foo] = {:bar => 1} @conditions[:foo] = {:bar => 1}
@conditions[:test] = 1 @conditions[:test] = 1

View File

@@ -53,19 +53,25 @@ describe CanCan::ControllerAdditions do
end end
it "load_and_authorize_resource should setup a before filter which passes call to ControllerResource" do it "load_and_authorize_resource should setup a before filter which passes call to ControllerResource" do
stub(CanCan::ControllerResource).new(@controller, :foo => :bar).mock!.load_and_authorize_resource stub(CanCan::ControllerResource).new(@controller, nil, :foo => :bar).mock!.load_and_authorize_resource
mock(@controller_class).before_filter({}) { |options, block| block.call(@controller) } mock(@controller_class).before_filter({}) { |options, block| block.call(@controller) }
@controller_class.load_and_authorize_resource :foo => :bar @controller_class.load_and_authorize_resource :foo => :bar
end end
it "load_and_authorize_resource should properly pass first argument as the resource name" do
stub(CanCan::ControllerResource).new(@controller, :project, :foo => :bar).mock!.load_and_authorize_resource
mock(@controller_class).before_filter({}) { |options, block| block.call(@controller) }
@controller_class.load_and_authorize_resource :project, :foo => :bar
end
it "authorize_resource should setup a before filter which passes call to ControllerResource" do it "authorize_resource should setup a before filter which passes call to ControllerResource" do
stub(CanCan::ControllerResource).new(@controller, :foo => :bar).mock!.authorize_resource stub(CanCan::ControllerResource).new(@controller, nil, :foo => :bar).mock!.authorize_resource
mock(@controller_class).before_filter(:except => :show) { |options, block| block.call(@controller) } mock(@controller_class).before_filter(:except => :show) { |options, block| block.call(@controller) }
@controller_class.authorize_resource :foo => :bar, :except => :show @controller_class.authorize_resource :foo => :bar, :except => :show
end end
it "load_resource should setup a before filter which passes call to ControllerResource" do it "load_resource should setup a before filter which passes call to ControllerResource" do
stub(CanCan::ControllerResource).new(@controller, :foo => :bar).mock!.load_resource stub(CanCan::ControllerResource).new(@controller, nil, :foo => :bar).mock!.load_resource
mock(@controller_class).before_filter(:only => [:show, :index]) { |options, block| block.call(@controller) } mock(@controller_class).before_filter(:only => [:show, :index]) { |options, block| block.call(@controller) }
@controller_class.load_resource :foo => :bar, :only => [:show, :index] @controller_class.load_resource :foo => :bar, :only => [:show, :index]
end end

View File

@@ -19,25 +19,29 @@ class Ability
end end
end end
# this class helps out in testing nesting and SQL conditions # this class helps out in testing SQL conditions
class Person class Person
def self.sanitize_sql(hash_cond) class << self
case hash_cond protected
when Hash
sanitize_hash(hash_cond).join(' AND ') def sanitize_sql(hash_cond)
when Array case hash_cond
hash_cond.shift.gsub('?'){"#{hash_cond.shift.inspect}"} when Hash
when String then hash_cond sanitize_hash(hash_cond).join(' AND ')
when Array
hash_cond.shift.gsub('?'){"#{hash_cond.shift.inspect}"}
when String then hash_cond
end
end
def sanitize_hash(hash)
hash.map do |name, value|
if Hash === value
sanitize_hash(value).map{|cond| "#{name}.#{cond}"}
else
"#{name}=#{value}"
end
end.flatten
end end
end end
def self.sanitize_hash(hash)
hash.map do |name, value|
if Hash === value
sanitize_hash(value).map{|cond| "#{name}.#{cond}"}
else
"#{name}=#{value}"
end
end.flatten
end
end end