allow Active Record scope to be passed as Ability conditions - closes #257
This commit is contained in:
parent
80f1ab20fb
commit
f9b181af05
|
@ -55,7 +55,9 @@ module CanCan
|
||||||
end
|
end
|
||||||
|
|
||||||
def database_records
|
def database_records
|
||||||
if @model_class.respond_to?(:where) && @model_class.respond_to?(:joins)
|
if override_scope
|
||||||
|
override_scope
|
||||||
|
elsif @model_class.respond_to?(:where) && @model_class.respond_to?(:joins)
|
||||||
@model_class.where(conditions).joins(joins)
|
@model_class.where(conditions).joins(joins)
|
||||||
else
|
else
|
||||||
@model_class.scoped(:conditions => conditions, :joins => joins)
|
@model_class.scoped(:conditions => conditions, :joins => joins)
|
||||||
|
@ -64,6 +66,18 @@ module CanCan
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def override_scope
|
||||||
|
conditions = @rules.map(&:conditions).compact
|
||||||
|
if conditions.any? { |c| c.kind_of?(ActiveRecord::Relation) }
|
||||||
|
if conditions.size == 1
|
||||||
|
conditions.first
|
||||||
|
else
|
||||||
|
rule = @rules.detect { |rule| rule.conditions.kind_of?(ActiveRecord::Relation) }
|
||||||
|
raise Error, "Unable to merge an Active Record scope with other conditions. Instead use a hash or SQL for #{rule.actions.first} #{rule.subjects.first} ability."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def merge_conditions(sql, conditions_hash, behavior)
|
def merge_conditions(sql, conditions_hash, behavior)
|
||||||
if conditions_hash.blank?
|
if conditions_hash.blank?
|
||||||
behavior ? true_sql : false_sql
|
behavior ? true_sql : false_sql
|
||||||
|
|
|
@ -3,7 +3,7 @@ module CanCan
|
||||||
# it holds the information about a "can" call made on Ability and provides
|
# it holds the information about a "can" call made on Ability and provides
|
||||||
# helpful methods to determine permission checking and conditions hash generation.
|
# helpful methods to determine permission checking and conditions hash generation.
|
||||||
class Rule # :nodoc:
|
class Rule # :nodoc:
|
||||||
attr_reader :base_behavior, :actions, :conditions
|
attr_reader :base_behavior, :subjects, :actions, :conditions
|
||||||
attr_writer :expanded_actions
|
attr_writer :expanded_actions
|
||||||
|
|
||||||
# The first argument when initializing is the base_behavior which is a true/false
|
# The first argument when initializing is the base_behavior which is a true/false
|
||||||
|
|
|
@ -110,10 +110,25 @@ if ENV["MODEL_ADAPTER"].nil? || ENV["MODEL_ADAPTER"] == "active_record"
|
||||||
@ability.can :read, Article, :published => true
|
@ability.can :read, Article, :published => true
|
||||||
@ability.can :read, Article, ["secret=?", true]
|
@ability.can :read, Article, ["secret=?", true]
|
||||||
article1 = Article.create!(:published => true, :secret => false)
|
article1 = Article.create!(:published => true, :secret => false)
|
||||||
|
article2 = Article.create!(:published => true, :secret => true)
|
||||||
|
article3 = Article.create!(:published => false, :secret => true)
|
||||||
article4 = Article.create!(:published => false, :secret => false)
|
article4 = Article.create!(:published => false, :secret => false)
|
||||||
|
Article.accessible_by(@ability).should == [article1, article2, article3]
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should allow a scope for conditions" do
|
||||||
|
@ability.can :read, Article, Article.where(:secret => true)
|
||||||
|
article1 = Article.create!(:secret => true)
|
||||||
|
article2 = Article.create!(:secret => false)
|
||||||
Article.accessible_by(@ability).should == [article1]
|
Article.accessible_by(@ability).should == [article1]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "should raise an exception when trying to merge scope with other conditions" do
|
||||||
|
@ability.can :read, Article, :published => true
|
||||||
|
@ability.can :read, Article, Article.where(:secret => true)
|
||||||
|
lambda { Article.accessible_by(@ability) }.should raise_error(CanCan::Error, "Unable to merge an Active Record scope with other conditions. Instead use a hash or SQL for read Article ability.")
|
||||||
|
end
|
||||||
|
|
||||||
it "should not allow to fetch records when ability with just block present" do
|
it "should not allow to fetch records when ability with just block present" do
|
||||||
@ability.can :read, Article do
|
@ability.can :read, Article do
|
||||||
false
|
false
|
||||||
|
|
Loading…
Reference in New Issue
Block a user