switching mongoid over to new adapter

This commit is contained in:
Ryan Bates 2010-12-30 15:06:59 -08:00
parent f5dce44697
commit f7a494dc51
2 changed files with 28 additions and 34 deletions

View File

@ -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

View File

@ -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