use Item.new instead of build_item for singleton resource so it doesn't mess up database - closes #304
This commit is contained in:
parent
fdd5ad022d
commit
3f6cecbfcf
|
@ -82,10 +82,10 @@ module CanCan
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_resource
|
def build_resource
|
||||||
method_name = @options[:singleton] && resource_base.respond_to?("build_#{name}") ? "build_#{name}" : "new"
|
resource = resource_base.new(@params[name] || {})
|
||||||
resource = resource_base.send(method_name, @params[name] || {})
|
resource.send("#{parent_name}=", parent_resource) if @options[:singleton] && parent_resource
|
||||||
initial_attributes.each do |name, value|
|
initial_attributes.each do |attr_name, value|
|
||||||
resource.send("#{name}=", value)
|
resource.send("#{attr_name}=", value)
|
||||||
end
|
end
|
||||||
resource
|
resource
|
||||||
end
|
end
|
||||||
|
@ -97,8 +97,8 @@ module CanCan
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_resource
|
def find_resource
|
||||||
if @options[:singleton] && resource_base.respond_to?(name)
|
if @options[:singleton] && parent_resource.respond_to?(name)
|
||||||
resource_base.send(name)
|
parent_resource.send(name)
|
||||||
else
|
else
|
||||||
@options[:find_by] ? resource_base.send("find_by_#{@options[:find_by]}!", id_param) : resource_base.find(id_param)
|
@options[:find_by] ? resource_base.send("find_by_#{@options[:find_by]}!", id_param) : resource_base.find(id_param)
|
||||||
end
|
end
|
||||||
|
@ -155,7 +155,7 @@ module CanCan
|
||||||
def resource_base
|
def resource_base
|
||||||
if @options[:through]
|
if @options[:through]
|
||||||
if parent_resource
|
if parent_resource
|
||||||
@options[:singleton] ? parent_resource : parent_resource.send(@options[:through_association] || name.to_s.pluralize)
|
@options[:singleton] ? resource_class : parent_resource.send(@options[:through_association] || name.to_s.pluralize)
|
||||||
elsif @options[:shallow]
|
elsif @options[:shallow]
|
||||||
resource_class
|
resource_class
|
||||||
else
|
else
|
||||||
|
@ -166,9 +166,13 @@ module CanCan
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def parent_name
|
||||||
|
@options[:through] && [@options[:through]].flatten.detect { |i| fetch_parent(i) }
|
||||||
|
end
|
||||||
|
|
||||||
# The object to load this resource through.
|
# The object to load this resource through.
|
||||||
def parent_resource
|
def parent_resource
|
||||||
@options[:through] && [@options[:through]].flatten.map { |i| fetch_parent(i) }.compact.first
|
parent_name && fetch_parent(parent_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_parent(name)
|
def fetch_parent(name)
|
||||||
|
|
|
@ -268,14 +268,14 @@ describe CanCan::ControllerResource do
|
||||||
@controller.instance_variable_get(:@project).should == :some_project
|
@controller.instance_variable_get(:@project).should == :some_project
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should build record through has_one association with :singleton option" do
|
it "should not build record through has_one association with :singleton option because it can cause it to delete it in the database" do
|
||||||
@params.merge!(:action => "create", :project => {:name => "foobar"})
|
@params.merge!(:action => "create", :project => {:name => "foobar"})
|
||||||
category = Object.new
|
category = Category.new
|
||||||
@controller.instance_variable_set(:@category, category)
|
@controller.instance_variable_set(:@category, category)
|
||||||
stub(category).build_project { |attributes| Project.new(attributes) }
|
|
||||||
resource = CanCan::ControllerResource.new(@controller, :through => :category, :singleton => true)
|
resource = CanCan::ControllerResource.new(@controller, :through => :category, :singleton => true)
|
||||||
resource.load_resource
|
resource.load_resource
|
||||||
@controller.instance_variable_get(:@project).name.should == "foobar"
|
@controller.instance_variable_get(:@project).name.should == "foobar"
|
||||||
|
@controller.instance_variable_get(:@project).category.should == category
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should find record through has_one association with :singleton and :shallow options" do
|
it "should find record through has_one association with :singleton and :shallow options" do
|
||||||
|
|
|
@ -29,4 +29,5 @@ end
|
||||||
|
|
||||||
class Project < SuperModel::Base
|
class Project < SuperModel::Base
|
||||||
belongs_to :category
|
belongs_to :category
|
||||||
|
attr_accessor :category # why doesn't SuperModel do this automatically?
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user