Added ability to specify the name of the child element as referenced within the parent #171

Closed
wants to merge 11 commits into
from
View
@@ -1,6 +1,6 @@
Gem::Specification.new do |s|
s.name = "cancan"
- s.version = "1.4.0"
+ s.version = "1.4.1"
s.author = "Ryan Bates"
s.email = "ryan@railscasts.com"
s.homepage = "http://github.com/ryanb/cancan"
@@ -62,6 +62,13 @@ def load_collection
def build_resource
resource = resource_base.send(@options[:singleton] ? "build_#{name}" : "new")
+
+ # If this resource has and belongs to many of the parent resource elements, the parent must be added to this resource's parent array
+ if (parent_resource_through && resource.respond_to?(parent_resource_through.to_s.pluralize))
+ resource.send("#{parent_resource_through.to_s.pluralize}") << parent_resource
+ resource_base.send("delete", resource)
+ end
+
initial_attributes.each do |name, value|
resource.send("#{name}=", value)
end
@@ -132,7 +139,7 @@ def collection_instance
def resource_base
if @options[:through]
if parent_resource
- @options[:singleton] ? parent_resource : parent_resource.send(name.to_s.pluralize)
+ @options[:singleton] ? parent_resource : parent_resource.send(@options[:name_in_parent] || name.to_s.pluralize)
elsif @options[:shallow]
resource_class
else
@@ -147,6 +154,11 @@ def resource_base
def parent_resource
@options[:through] && [@options[:through]].flatten.map { |i| fetch_parent(i) }.compact.first
end
+
+ # Gets the name of the parent to load the resource through
+ def parent_resource_through
+ @options[:through] && [@options[:through]].flatten.map { |i| fetch_parent(i) ? i : nil }.compact.first
+ end
def fetch_parent(name)
if @controller.instance_variable_defined? "@#{name}"
@@ -280,6 +280,16 @@
resource.load_resource
@controller.instance_variable_get(:@project).should == project
end
+
+ it "should allow you to specify the name of the child resource as specified in the parent" do
+ @params.merge!(:action => "show", :id => 123)
+ category = Object.new
+ stub(@controller).category { category }
+ stub(category).children.stub!.find(123) { :some_project }
+ resource = CanCan::ControllerResource.new(@controller, :through => :category, :name_in_parent => :children)
+ resource.load_resource
+ @controller.instance_variable_get(:@project).should == :some_project
+ end
it "should raise ImplementationRemoved when adding :name option" do
lambda {