Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

DataMapper adapter improvements #355

Merged
merged 3 commits into from

2 participants

@emmanuel

I'm sure there's more to be done, but this gets the pending spec passing, at least. Also eliminates the round-trip to the database to evaluate conditions on a single resource (DataMapperAdapter.matches_conditions_hash?).

At the moment I don't see how to associate this pull request with ryanb/cancan#245 but it is meant as a fix for that issue.

@ryanb
Owner

Awesome thanks! I'll get this pulled in soon.

@ryanb ryanb merged commit ff13a82 into ryanb:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
23 lib/cancan/model_adapters/data_mapper_adapter.rb
@@ -10,23 +10,22 @@ def self.override_conditions_hash_matching?(subject, conditions)
end
def self.matches_conditions_hash?(subject, conditions)
- subject.class.all(:conditions => conditions).include?(subject) # TODO don't use a database query here for performance and other instances
+ collection = DataMapper::Collection.new(subject.query, [ subject ])
+ !!collection.first(conditions)
end
def database_records
- scope = @model_class.all(:conditions => ["0=1"])
- conditions.each do |condition|
- scope += @model_class.all(:conditions => condition)
- end
+ scope = @model_class.all(:conditions => ["0 = 1"])
+ cans, cannots = @rules.partition { |r| r.base_behavior }
+ return scope if cans.empty?
+ # apply unions first, then differences. this mean cannot overrides can
+ cans.each { |r| scope += @model_class.all(:conditions => r.conditions) }
+ cannots.each { |r| scope -= @model_class.all(:conditions => r.conditions) }
scope
end
-
- def conditions
- @rules.map(&:conditions)
- end
- end
- end
-end
+ end # class DataMapper
+ end # module ModelAdapters
+end # module CanCan
DataMapper::Model.class_eval do
include CanCan::ModelAdditions::ClassMethods
View
1  spec/cancan/model_adapters/data_mapper_adapter_spec.rb
@@ -65,7 +65,6 @@ class Comment
end
it "should fetch only the articles that are published and not secret" do
- pending "the `cannot` may require some custom SQL, maybe abstract out from Active Record adapter"
@ability.can :read, Article, :published => true
@ability.cannot :read, Article, :secret => true
article1 = Article.create(:published => true, :secret => false)
Something went wrong with that request. Please try again.