include namespace in params when creating/updating resource - closes #349

This commit is contained in:
Ryan Bates 2011-09-28 16:00:46 -07:00
parent 6de9e4675a
commit c94de4ab18
6 changed files with 38 additions and 26 deletions

View File

@ -10,7 +10,7 @@ Gem::Specification.new do |s|
s.files = Dir["{lib,spec}/**/*", "[A-Z]*", "init.rb"] - ["Gemfile.lock"] s.files = Dir["{lib,spec}/**/*", "[A-Z]*", "init.rb"] - ["Gemfile.lock"]
s.require_path = "lib" s.require_path = "lib"
s.add_development_dependency 'rspec', '~> 2.1.0' 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 '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' s.add_development_dependency 'supermodel', '~> 0.1.4'

View File

@ -29,8 +29,8 @@ module CanCan
end end
if @options[:authorize] if @options[:authorize]
if resource_instance if resource_instance
if @params[name] && (authorization_action == :create || authorization_action == :update) if resource_params && (authorization_action == :create || authorization_action == :update)
@params[name].each do |key, value| resource_params.each do |key, value|
@controller.authorize!(authorization_action, resource_instance, key.to_sym) @controller.authorize!(authorization_action, resource_instance, key.to_sym)
end end
else else
@ -80,7 +80,7 @@ module CanCan
end end
def build_resource def build_resource
resource = resource_base.new(@params[name] || {}) resource = resource_base.new(resource_params || {})
resource.send("#{parent_name}=", parent_resource) if @options[:singleton] && parent_resource resource.send("#{parent_name}=", parent_resource) if @options[:singleton] && parent_resource
initial_attributes.each do |attr_name, value| initial_attributes.each do |attr_name, value|
resource.send("#{attr_name}=", value) resource.send("#{attr_name}=", value)
@ -90,15 +90,15 @@ module CanCan
def initial_attributes def initial_attributes
current_ability.attributes_for(@params[:action].to_sym, subject_name).delete_if do |key, value| current_ability.attributes_for(@params[:action].to_sym, subject_name).delete_if do |key, value|
@params[name] && @params[name].include?(key) resource_params && resource_params.include?(key)
end end
end end
def find_and_update_resource def find_and_update_resource
resource = find_resource resource = find_resource
if @params[name] if resource_params
@controller.authorize!(authorization_action, resource) if @options[:authorize] @controller.authorize!(authorization_action, resource) if @options[:authorize]
resource.attributes = @params[name] resource.attributes = resource_params
end end
resource resource
end end
@ -224,6 +224,11 @@ module CanCan
@name || name_from_controller @name || name_from_controller
end end
def resource_params
# since Rails includes the namespace in the params sent by the form (issue #349)
@params[namespaced_name.to_s.underscore.gsub("/", "_")]
end
def namespaced_name def namespaced_name
@params[:controller].sub("Controller", "").singularize.camelize.constantize @params[:controller].sub("Controller", "").singularize.camelize.constantize
rescue NameError rescue NameError

View File

@ -33,17 +33,6 @@ describe CanCan::ControllerResource do
@controller.instance_variable_get(:@project).should == project @controller.instance_variable_get(:@project).should == project
end end
it "should attempt to load a resource with the same namespace as the controller when using :: for namespace" do
module MyEngine
class Project < ::Project; end
end
project = MyEngine::Project.create!
@params.merge!(:controller => "MyEngine::ProjectsController", :action => "show", :id => project.id)
resource = CanCan::ControllerResource.new(@controller, :load => true)
resource.process
@controller.instance_variable_get(:@project).should == project
end
it "should properly load resource for namespaced controller when using '::' for namespace" do it "should properly load resource for namespaced controller when using '::' for namespace" do
project = Project.create! project = Project.create!
@params.merge!(:controller => "Admin::ProjectsController", :action => "show", :id => project.id) @params.merge!(:controller => "Admin::ProjectsController", :action => "show", :id => project.id)
@ -351,8 +340,7 @@ describe CanCan::ControllerResource do
it "should allow full find method to be passed into find_by option" do it "should allow full find method to be passed into find_by option" do
project = Project.create!(:name => "foo") project = Project.create!(:name => "foo")
@params.merge!(:action => "show", :id => "foo") @params.merge!(:action => "show", :id => "foo")
resource = CanCan::ControllerResource.new(@controller, :find_by => :find_by_name, :load => true) CanCan::ControllerResource.new(@controller, :find_by => :find_by_name, :load => true).process
resource.process
@controller.instance_variable_get(:@project).should == project @controller.instance_variable_get(:@project).should == project
end end
@ -371,6 +359,26 @@ describe CanCan::ControllerResource do
lambda { resource.process }.should raise_error(CanCan::Unauthorized) lambda { resource.process }.should raise_error(CanCan::Unauthorized)
end end
it "should attempt to load a resource with the same namespace as the controller when using :: for namespace" do
module Namespaced
class Project < ::Project; end
end
project = Namespaced::Project.create!
@params.merge!(:controller => "Namespaced::ProjectsController", :action => "show", :id => project.id)
CanCan::ControllerResource.new(@controller, :load => true).process
@controller.instance_variable_get(:@project).should == project
end
# Rails includes namespace in params, see issue #349
it "should create through namespaced params" do
module Namespaced
class Project < ::Project; end
end
@params.merge!(:controller => "Namespaced::ProjectsController", :action => "create", :namespaced_project => {:name => "foobar"})
CanCan::ControllerResource.new(@controller, :load => true).process
@controller.instance_variable_get(:@project).name.should == "foobar"
end
# it "should raise ImplementationRemoved when adding :name option" do # it "should raise ImplementationRemoved when adding :name option" do
# lambda { # lambda {
# CanCan::ControllerResource.new(@controller, :name => :foo) # CanCan::ControllerResource.new(@controller, :name => :foo)

View File

@ -1,10 +1,6 @@
if ENV["MODEL_ADAPTER"].nil? || ENV["MODEL_ADAPTER"] == "active_record" if ENV["MODEL_ADAPTER"].nil? || ENV["MODEL_ADAPTER"] == "active_record"
require "spec_helper" require "spec_helper"
RSpec.configure do |config|
config.extend WithModel
end
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:") ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
describe CanCan::ModelAdapters::ActiveRecordAdapter do describe CanCan::ModelAdapters::ActiveRecordAdapter do

View File

@ -1,2 +0,0 @@
--color
--backtrace

View File

@ -9,11 +9,16 @@ require 'matchers'
require 'cancan/matchers' require 'cancan/matchers'
RSpec.configure do |config| RSpec.configure do |config|
config.treat_symbols_as_metadata_keys_with_true_values = true
config.filter_run :focus => true
config.run_all_when_everything_filtered = true
config.mock_with :rr config.mock_with :rr
config.before(:each) do config.before(:each) do
Project.delete_all Project.delete_all
Category.delete_all Category.delete_all
end end
config.extend WithModel
end end
class Ability class Ability