From f7a494dc519297a915ca1d43ea78a461a643f2b8 Mon Sep 17 00:00:00 2001 From: Ryan Bates Date: Thu, 30 Dec 2010 15:06:59 -0800 Subject: [PATCH] switching mongoid over to new adapter --- lib/cancan/model_adapters/mongoid_adapter.rb | 53 +++++++------------ .../model_adapters/mongoid_adapter_spec.rb | 9 +++- 2 files changed, 28 insertions(+), 34 deletions(-) diff --git a/lib/cancan/model_adapters/mongoid_adapter.rb b/lib/cancan/model_adapters/mongoid_adapter.rb index 3eafddb..30ca98c 100644 --- a/lib/cancan/model_adapters/mongoid_adapter.rb +++ b/lib/cancan/model_adapters/mongoid_adapter.rb @@ -1,37 +1,26 @@ module CanCan - module Ability - # could use alias_method_chain, but it's not worth adding activesupport as a gem dependency - alias_method :query_without_mongoid_support, :query - def query(action, subject) - if defined?(::Mongoid) && subject <= CanCan::MongoidAdditions - query_with_mongoid_support(action, subject) - else - query_without_mongoid_support(action, subject) + module ModelAdapters + class MongoidAdapter < AbstractAdapter + def self.for_class?(model_class) + model_class <= CanCan::MongoidAdditions # there should be a better class to detect with this end - end - def query_with_mongoid_support(action, subject) - MongoidQuery.new(subject, relevant_rules_for_query(action, subject)) - end - end - - class MongoidQuery - def initialize(sanitizer, rules) - @sanitizer = sanitizer - @rules = rules - end - - def conditions - if @rules.size == 0 - false_query - else - @rules.first.instance_variable_get(:@conditions) + def database_records + @model_class.where(conditions) end - end - def false_query - # this query is sure to return no results - {:_id => {'$exists' => false, '$type' => 7}} # type 7 is an ObjectID (default for _id) + def conditions + if @rules.size == 0 + false_query + else + @rules.first.conditions + end + end + + def false_query + # this query is sure to return no results + {:_id => {'$exists' => false, '$type' => 7}} # type 7 is an ObjectID (default for _id) + end end end @@ -62,8 +51,6 @@ module CanCan alias_method :matches_conditions_hash?, :matches_conditions_hash_with_mongoid_subject? end - - module MongoidAdditions module ClassMethods # Returns a scope which fetches only the records that the passed ability @@ -84,8 +71,7 @@ module CanCan # Here only the articles which the user can update are returned. This # internally uses Ability#conditions method, see that for more information. def accessible_by(ability, action = :read) - query = ability.query(action, self) - where(query.conditions) + ability.model_adapter(self, action).database_records end end @@ -97,6 +83,7 @@ end # Info on monkeypatching Mongoid : # http://log.mazniak.org/post/719062325/monkey-patching-activesupport-concern-and-you#footer +# This link is now broken, anyone know what it was referring to? if defined?(::Mongoid) module Mongoid module Components diff --git a/spec/cancan/model_adapters/mongoid_adapter_spec.rb b/spec/cancan/model_adapters/mongoid_adapter_spec.rb index 5430e96..bbf1718 100644 --- a/spec/cancan/model_adapters/mongoid_adapter_spec.rb +++ b/spec/cancan/model_adapters/mongoid_adapter_spec.rb @@ -37,7 +37,7 @@ if ENV["MODEL_ADAPTER"] == "mongoid" config.master = Mongo::Connection.new('127.0.0.1', 27017).db("cancan_mongoid_spec") end - describe CanCan::MongoidAdditions do + describe CanCan::ModelAdapters::MongoidAdapter do context "Mongoid not defined" do before(:all) do @mongoid_class = Object.send(:remove_const, :Mongoid) @@ -46,6 +46,7 @@ if ENV["MODEL_ADAPTER"] == "mongoid" after(:all) do Object.const_set(:Mongoid, @mongoid_class) end + it "should not raise an error for ActiveRecord models" do @model_class = Class.new(Project) stub(@model_class).scoped { :scoped_stub } @@ -72,6 +73,12 @@ if ENV["MODEL_ADAPTER"] == "mongoid" end.each(&:drop) end + it "should be for only Mongoid classes" do + CanCan::ModelAdapters::MongoidAdapter.should_not be_for_class(Object) + CanCan::ModelAdapters::MongoidAdapter.should be_for_class(@model_class) + CanCan::ModelAdapters::AbstractAdapter.adapter_class(@model_class).should == CanCan::ModelAdapters::MongoidAdapter + end + it "should compare properties on mongoid documents with the conditions hash" do model = @model_class.new @ability.can :read, @model_class, :id => model.id