Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Add support Mass-Assignment Role of ActiveRecord + specs #662

Closed
wants to merge 4 commits into
from
View
@@ -6,6 +6,10 @@ when nil, "active_record"
gem "activerecord", '~> 3.0.9', :require => "active_record"
gem "with_model", "~> 0.2.5"
gem "meta_where"
+when "active_record_31"
+ gem "sqlite3"
+ gem "activerecord", '~> 3.1.6', :require => "active_record"
+ gem "with_model", "~> 0.2.5"
when "data_mapper"
gem "dm-core", "~> 1.0.2"
gem "dm-sqlite-adapter", "~> 1.0.2"
View
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
s.require_path = "lib"
s.add_development_dependency 'rspec', '~> 2.6.0'
- s.add_development_dependency 'rails', '~> 3.0.9'
+ s.add_development_dependency 'rails', '> 3.0.9'
s.add_development_dependency 'rr', '~> 0.10.11' # 1.0.0 has respond_to? issues: http://github.com/btakita/rr/issues/issue/43
s.add_development_dependency 'supermodel', '~> 0.1.4'
@@ -112,6 +112,9 @@ def load_and_authorize_resource(*args)
# [:+prepend+]
# Passing +true+ will use prepend_before_filter instead of a normal before_filter.
#
+ # [:+assign_as+]
+ # Passed as the role when mass assigning attributes (from Rails 3.1 onwards)
+ #
def load_resource(*args)
cancan_resource_class.add_before_filter(self, :load_resource, *args)
end
@@ -82,7 +82,12 @@ def load_collection
end
def build_resource
- resource = resource_base.new(resource_params || {})
+ # use Rails 3.1's assign_attribute when resource_params[:assign_as] is present
+ if @options && @options[:assign_as].present? && (resource = resource_base.new).respond_to?(:assign_attributes)
+ resource.assign_attributes(resource_params || {}, :as => @options[:assign_as])
+ else
+ resource = resource_base.new(resource_params || {})
+ end
assign_attributes(resource)
end
@@ -465,4 +465,51 @@ class Section
lambda { resource.load_and_authorize_resource }.should_not raise_error
@controller.instance_variable_get(:@project).should be_nil
end
+
+ if ENV["MODEL_ADAPTER"] == "active_record_31"
+ context "using an ActiveRecord model with :as" do
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:") unless ActiveRecord::Base.connected?
+
+ with_model :project do
+ table do |t|
+ t.string "name"
+ t.boolean "secret", :default => false
+ end
+ model do
+ attr_accessible :name
+ attr_accessible :name, :secret, :as => :admin
+ end
+ end
+
+ it "should be able to mass assign name" do
+ @params.merge!(:action => "create", :project => { :name => "foobar" })
+ resource = CanCan::ControllerResource.new(@controller)
+ resource.load_resource
+
+ project = @controller.instance_variable_get(:@project)
+ project.name.should eql("foobar")
+ project.secret.should be_false
+ end
+
+ it "should not be able to mass assign secret" do
+ @params.merge!(:action => "create", :project => { :name => "foobar", :secret => "1" })
+ resource = CanCan::ControllerResource.new(@controller)
+ resource.load_resource
+
+ project = @controller.instance_variable_get(:@project)
+ project.name.should eql("foobar")
+ project.secret.should be_false
+ end
+
+ it "should be able to mass assign secret when using :assign_as" do
+ @params.merge!(:action => "create", :project => { :name => "foobar", :secret => "1" })
+ resource = CanCan::ControllerResource.new(@controller, :assign_as => :admin)
+ resource.load_resource
+
+ project = @controller.instance_variable_get(:@project)
+ project.name.should eql("foobar")
+ project.secret.should be_true
+ end
+ end
+ end
end
@@ -1,7 +1,7 @@
if ENV["MODEL_ADAPTER"].nil? || ENV["MODEL_ADAPTER"] == "active_record"
require "spec_helper"
- ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:") unless ActiveRecord::Base.connected?
describe CanCan::ModelAdapters::ActiveRecordAdapter do
with_model :category do
View
@@ -17,7 +17,7 @@
Project.delete_all
Category.delete_all
end
- config.extend WithModel if ENV["MODEL_ADAPTER"].nil? || ENV["MODEL_ADAPTER"] == "active_record"
+ config.extend WithModel if ENV["MODEL_ADAPTER"].nil? || /active_record/ =~ ENV["MODEL_ADAPTER"]
end
class Ability