adding initial MetaWhere support

This commit is contained in:
Ryan Bates 2011-03-08 10:37:25 -08:00
parent 52435e97d9
commit ff5aaf543b
4 changed files with 47 additions and 10 deletions

View File

@ -26,6 +26,17 @@ module CanCan
raise NotImplemented, "This model adapter does not support matching on a conditions hash." raise NotImplemented, "This model adapter does not support matching on a conditions hash."
end end
# Used to determine if this model adapter will override the matching behavior for a specific condition.
# If this returns true then matches_condition? will be called. See Rule#matches_conditions_hash
def self.override_condition_matching?(subject, name, value)
false
end
# Override if override_condition_matching? returns true
def self.matches_condition?(subject, name, value)
raise NotImplemented, "This model adapter does not support matching on a specific condition."
end
def initialize(model_class, rules) def initialize(model_class, rules)
@model_class = model_class @model_class = model_class
@rules = rules @rules = rules

View File

@ -5,6 +5,16 @@ module CanCan
model_class <= ActiveRecord::Base model_class <= ActiveRecord::Base
end end
def self.override_condition_matching?(subject, name, value)
name.kind_of?(MetaWhere::Column) if defined? MetaWhere
end
def self.matches_condition?(subject, name, value)
case name.method
when "lt" then subject.send(name.column) < value
end
end
# Returns conditions intended to be used inside a database query. Normally you will not call this # Returns conditions intended to be used inside a database query. Normally you will not call this
# method directly, but instead go through ModelAdditions#accessible_by. # method directly, but instead go through ModelAdditions#accessible_by.
# #

View File

@ -100,17 +100,21 @@ module CanCan
model_adapter(subject).matches_conditions_hash? subject, conditions model_adapter(subject).matches_conditions_hash? subject, conditions
else else
conditions.all? do |name, value| conditions.all? do |name, value|
attribute = subject.send(name) if model_adapter(subject).override_condition_matching? subject, name, value
if value.kind_of?(Hash) model_adapter(subject).matches_condition? subject, name, value
if attribute.kind_of? Array
attribute.any? { |element| matches_conditions_hash? element, value }
else
matches_conditions_hash? attribute, value
end
elsif value.kind_of?(Array) || value.kind_of?(Range)
value.include? attribute
else else
attribute == value attribute = subject.send(name)
if value.kind_of?(Hash)
if attribute.kind_of? Array
attribute.any? { |element| matches_conditions_hash? element, value }
else
matches_conditions_hash? attribute, value
end
elsif value.kind_of?(Array) || value.kind_of?(Range)
value.include? attribute
else
attribute == value
end
end end
end end
end end

View File

@ -21,6 +21,7 @@ if ENV["MODEL_ADAPTER"].nil? || ENV["MODEL_ADAPTER"] == "active_record"
table do |t| table do |t|
t.boolean "published" t.boolean "published"
t.boolean "secret" t.boolean "secret"
t.integer "priority"
t.integer "category_id" t.integer "category_id"
end end
model do model do
@ -199,5 +200,16 @@ if ENV["MODEL_ADAPTER"].nil? || ENV["MODEL_ADAPTER"] == "active_record"
@ability.can :read, Article, :project => { :admin => true } @ability.can :read, Article, :project => { :admin => true }
@ability.model_adapter(Article, :read).joins.should == [:project] @ability.model_adapter(Article, :read).joins.should == [:project]
end end
describe "with MetaWhere" do
it "should read articles where priority is less than 2" do
@ability.can :read, Article, :priority.lt => 2
article1 = Article.create!(:priority => 1)
article2 = Article.create!(:priority => 3)
Article.accessible_by(@ability).should == [article1]
@ability.should be_able_to(:read, article1)
@ability.should_not be_able_to(:read, article2)
end
end
end end
end end