dynamically detect which model adapter to use given a class
This commit is contained in:
parent
cc30e838c0
commit
bbb02f7c8f
2
Gemfile
2
Gemfile
|
@ -10,6 +10,8 @@ when "data_mapper"
|
|||
when "mongoid"
|
||||
gem "bson_ext", "~> 1.1"
|
||||
gem "mongoid", "~> 2.0.0.beta.19"
|
||||
else
|
||||
raise "Unknown model adapter: #{ENV["MODEL_ADAPTER"]}"
|
||||
end
|
||||
|
||||
gemspec
|
||||
|
|
|
@ -7,6 +7,7 @@ require 'cancan/query'
|
|||
require 'cancan/inherited_resource'
|
||||
|
||||
require 'cancan/model_adapters/abstract_adapter'
|
||||
require 'cancan/model_adapters/default_adapter'
|
||||
require 'cancan/model_adapters/active_record_adapter' if defined? ActiveRecord
|
||||
require 'cancan/model_adapters/data_mapper_adapter' if defined? DataMapper
|
||||
require 'cancan/model_adapters/mongoid_adapter' if defined? Mongoid
|
||||
|
|
|
@ -187,7 +187,8 @@ module CanCan
|
|||
end
|
||||
|
||||
def model_adapter(model_class, action)
|
||||
ModelAdapters::ActiveRecordAdapter.new(model_class, relevant_rules_for_query(action, model_class))
|
||||
adapter_class = ModelAdapters::AbstractAdapter.adapter_class(model_class)
|
||||
adapter_class.new(model_class, relevant_rules_for_query(action, model_class))
|
||||
end
|
||||
|
||||
# See ControllerAdditions#authorize! for documentation.
|
||||
|
|
|
@ -1,6 +1,20 @@
|
|||
module CanCan
|
||||
module ModelAdapters
|
||||
class AbstractAdapter
|
||||
def self.inherited(subclass)
|
||||
@subclasses ||= []
|
||||
@subclasses << subclass
|
||||
end
|
||||
|
||||
def self.adapter_class(model_class)
|
||||
@subclasses.detect { |subclass| subclass.for_class?(model_class) } || DefaultAdapter
|
||||
end
|
||||
|
||||
# Used to determine if the given adapter should be used for the passed in class.
|
||||
def self.for_class?(member_class)
|
||||
false # override in subclass
|
||||
end
|
||||
|
||||
def initialize(model_class, rules)
|
||||
@model_class = model_class
|
||||
@rules = rules
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
module CanCan
|
||||
module ModelAdapters
|
||||
class ActiveRecordAdapter < AbstractAdapter
|
||||
def self.for_class?(model_class)
|
||||
model_class <= ActiveRecord::Base
|
||||
end
|
||||
|
||||
# Returns conditions intended to be used inside a database query. Normally you will not call this
|
||||
# method directly, but instead go through ActiveRecordAdditions#accessible_by.
|
||||
#
|
||||
|
|
7
lib/cancan/model_adapters/default_adapter.rb
Normal file
7
lib/cancan/model_adapters/default_adapter.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
module CanCan
|
||||
module ModelAdapters
|
||||
class DefaultAdapter < AbstractAdapter
|
||||
# This adapter is used when no matching adapter is found
|
||||
end
|
||||
end
|
||||
end
|
|
@ -343,6 +343,14 @@ describe CanCan::Ability do
|
|||
end
|
||||
end
|
||||
|
||||
it "should determine model adapter class by asking AbstractAdapter" do
|
||||
model_class = Object.new
|
||||
adapter_class = Object.new
|
||||
stub(CanCan::ModelAdapters::AbstractAdapter).adapter_class(model_class) { adapter_class }
|
||||
stub(adapter_class).new(model_class, []) { :adapter_instance }
|
||||
@ability.model_adapter(model_class, :read).should == :adapter_instance
|
||||
end
|
||||
|
||||
describe "unauthorized message" do
|
||||
after(:each) do
|
||||
I18n.backend = nil
|
||||
|
|
|
@ -33,6 +33,12 @@ if ENV["MODEL_ADAPTER"].nil? || ENV["MODEL_ADAPTER"] == "active_record"
|
|||
@comment_table = Comment.table_name
|
||||
end
|
||||
|
||||
it "should be for only active record classes" do
|
||||
CanCan::ModelAdapters::ActiveRecordAdapter.should_not be_for_class(Object)
|
||||
CanCan::ModelAdapters::ActiveRecordAdapter.should be_for_class(Article)
|
||||
CanCan::ModelAdapters::AbstractAdapter.adapter_class(Article).should == CanCan::ModelAdapters::ActiveRecordAdapter
|
||||
end
|
||||
|
||||
it "should not fetch any records when no abilities are defined" do
|
||||
Article.create!
|
||||
Article.accessible_by(@ability).should be_empty
|
||||
|
|
7
spec/cancan/model_adapters/default_adapter_spec.rb
Normal file
7
spec/cancan/model_adapters/default_adapter_spec.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
require "spec_helper"
|
||||
|
||||
describe CanCan::ModelAdapters::DefaultAdapter do
|
||||
it "should be default for generic classes" do
|
||||
CanCan::ModelAdapters::AbstractAdapter.adapter_class(Object).should == CanCan::ModelAdapters::DefaultAdapter
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user