Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fixed bug with params for actions that build new instances with namespaced models #541

Merged
merged 1 commit into from

3 participants

@icrowley

Fixed bug with params for actions that build new instances with namespaced models

For example, I have a model Sub::Project and make the following call:
load_resource :instance_name => :project, :class => Sub::Project

when in the 'create' action CanCan waits for params[:project], no params[:sub_project]

This patch fixes it

@cgunther

I just hit this same bug.

The patch fixes it, but only if the class option is passed in, which I feel may be redundant.

Given a controller Accessory::ColorsController and a model Accessory::Color, I don't believe it should be necessary to pass in the class option.

I'll do some digging in the source and see what I can come up with.

@ryanb ryanb merged commit a8a85f1 into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 5, 2012
  1. @icrowley
This page is out of date. Refresh to see the latest.
View
5 lib/cancan/controller_resource.rb
@@ -82,7 +82,10 @@ def load_collection
end
def build_resource
- resource = resource_base.new(@params[name] || {})
+ params = @options[:class] \
+ ? @params[@options[:class].to_s.underscore.gsub('/', '_')] \
+ : @params[name] || {}
+ resource = resource_base.new(params)
resource.send("#{parent_name}=", parent_resource) if @options[:singleton] && parent_resource
initial_attributes.each do |attr_name, value|
resource.send("#{attr_name}=", value)
View
20 spec/cancan/controller_resource_spec.rb
@@ -62,6 +62,14 @@ class Project < ::Project; end
@controller.instance_variable_get(:@project).name.should == "foobar"
end
+ it "should build a new resource for namespaced model with hash if params[:id] is not specified" do
+ project = Sub::Project.create!
+ @params.merge!(:action => "create", 'sub_project' => {:name => "foobar"})
+ resource = CanCan::ControllerResource.new(@controller, :class => ::Sub::Project)
+ resource.load_resource
+ @controller.instance_variable_get(:@project).name.should == "foobar"
+ end
+
it "should build a new resource with attributes from current ability" do
@params.merge!(:action => "new")
@ability.can(:create, Project, :name => "from conditions")
@@ -324,6 +332,14 @@ class Project < ::Project; end
@controller.instance_variable_get(:@project).should == project
end
+ it "should load the model using a custom namespaced class" do
+ project = Sub::Project.create!
+ @params.merge!(:action => "show", :id => project.id)
+ resource = CanCan::ControllerResource.new(@controller, :class => ::Sub::Project)
+ resource.load_resource
+ @controller.instance_variable_get(:@project).should == project
+ end
+
it "should authorize based on resource name if class is false" do
@params.merge!(:action => "show", :id => 123)
stub(@controller).authorize!(:show, :project) { raise CanCan::AccessDenied }
@@ -339,7 +355,7 @@ class Project < ::Project; end
lambda { resource.load_and_authorize_resource }.should raise_error(CanCan::AccessDenied)
@controller.instance_variable_get(:@custom_project).should == project
end
-
+
it "should load resource using custom ID param" do
project = Project.create!
@params.merge!(:action => "show", :the_project => project.id)
@@ -347,7 +363,7 @@ class Project < ::Project; end
resource.load_resource
@controller.instance_variable_get(:@project).should == project
end
-
+
it "should load resource using custom find_by attribute" do
project = Project.create!(:name => "foo")
@params.merge!(:action => "show", :id => "foo")
View
15 spec/spec_helper.rb
@@ -31,6 +31,21 @@ class Category < SuperModel::Base
has_many :projects
end
+module Sub
+ class Project < SuperModel::Base
+ belongs_to :category
+ attr_accessor :category # why doesn't SuperModel do this automatically?
+
+ def self.respond_to?(method, include_private = false)
+ if method.to_s == "find_by_name!" # hack to simulate ActiveRecord
+ true
+ else
+ super
+ end
+ end
+ end
+end
+
class Project < SuperModel::Base
belongs_to :category
attr_accessor :category # why doesn't SuperModel do this automatically?
Something went wrong with that request. Please try again.