adding initial MetaWhere support
This commit is contained in:
parent
52435e97d9
commit
ff5aaf543b
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
#
|
#
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user