Skip to content

Instantly share code, notes, and snippets.

@roovo
Created April 13, 2009 16:55
Show Gist options
  • Save roovo/94535 to your computer and use it in GitHub Desktop.
Save roovo/94535 to your computer and use it in GitHub Desktop.
From 42c65f3201d294613d0549bf8312f4b01e91ae00 Mon Sep 17 00:00:00 2001
From: Rupert Voelcker <rupert@rupespad.com>
Date: Mon, 13 Apr 2009 16:22:02 +0100
Subject: [PATCH] fix for more complex has many through
---
.../nested_attributes.rb | 2 +-
spec/fixtures/photo.rb | 9 +
spec/fixtures/tag.rb | 12 ++
spec/fixtures/tagging.rb | 10 +
spec/integration/has_n_through_renamed_spec.rb | 201 ++++++++++++++++++++
5 files changed, 233 insertions(+), 1 deletions(-)
create mode 100644 spec/fixtures/photo.rb
create mode 100644 spec/fixtures/tag.rb
create mode 100644 spec/fixtures/tagging.rb
create mode 100644 spec/integration/has_n_through_renamed_spec.rb
diff --git a/lib/dm-accepts_nested_attributes/nested_attributes.rb b/lib/dm-accepts_nested_attributes/nested_attributes.rb
index 775017d..df44da7 100755
--- a/lib/dm-accepts_nested_attributes/nested_attributes.rb
+++ b/lib/dm-accepts_nested_attributes/nested_attributes.rb
@@ -252,7 +252,7 @@ module DataMapper
# do what's done in dm-core/specs/integration/association_through_spec.rb
# explicitly build the join entry and assign it to the join association
- join_entry = Extlib::Inflection.constantize(Extlib::Inflection.classify(association.name)).new
+ join_entry = self.class.associated_model_for_name(association.name).new
self.send(association.name) << join_entry
self.save
# explicitly build the child entry and assign the join entry to its join association
diff --git a/spec/fixtures/photo.rb b/spec/fixtures/photo.rb
new file mode 100644
index 0000000..43e8f1e
--- /dev/null
+++ b/spec/fixtures/photo.rb
@@ -0,0 +1,9 @@
+class Photo
+ include DataMapper::Resource
+
+ property :id, Serial
+ property :name, String
+
+ has n, :tagged_things, :class_name => "Tagging"
+ has n, :tags, :through => :tagged_things
+end
diff --git a/spec/fixtures/tag.rb b/spec/fixtures/tag.rb
new file mode 100644
index 0000000..49ad50c
--- /dev/null
+++ b/spec/fixtures/tag.rb
@@ -0,0 +1,12 @@
+class Tag
+ include DataMapper::Resource
+
+ property :id, Serial
+ property :name, String
+
+ has n, :tagged_things, :class_name => "Tagging"
+ has n, :pictures, :through => :tagged_things,
+ :class_name => 'Photo',
+ :child_key => [:tag_id],
+ :remote_name => :photo
+end
diff --git a/spec/fixtures/tagging.rb b/spec/fixtures/tagging.rb
new file mode 100644
index 0000000..b0e5066
--- /dev/null
+++ b/spec/fixtures/tagging.rb
@@ -0,0 +1,10 @@
+class Tagging
+ include DataMapper::Resource
+
+ property :id, Serial
+ property :tag_id, Integer
+ property :photo_id, Integer
+
+ belongs_to :tag
+ belongs_to :photo
+end
diff --git a/spec/integration/has_n_through_renamed_spec.rb b/spec/integration/has_n_through_renamed_spec.rb
new file mode 100644
index 0000000..652acd7
--- /dev/null
+++ b/spec/integration/has_n_through_renamed_spec.rb
@@ -0,0 +1,201 @@
+require 'pathname'
+require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
+
+describe DataMapper::NestedAttributes do
+
+ describe "every accessible has(n, :through) renamed association with a valid reject_if proc", :shared => true do
+
+ it "should not allow to create a new picture via Tag#pictures_attributes" do
+ @tag.save
+ Tag.all.size.should == 1
+ Tagging.all.size.should == 0
+ Photo.all.size.should == 0
+
+ @tag.pictures_attributes = { 'new_1' => { :name => 'dm-accepts_nested_attributes' } }
+ @tag.pictures.should be_empty
+ @tag.save
+
+ Tag.all.size.should == 1
+ Tagging.all.size.should == 0
+ Photo.all.size.should == 0
+ end
+
+ end
+
+ describe "every accessible has(n, :through) renamed association with no reject_if proc", :shared => true do
+
+ it "should allow to create a new picture via Tag#pictures_attributes" do
+ @tag.save
+ Tag.all.size.should == 1
+ Tagging.all.size.should == 0
+ Photo.all.size.should == 0
+
+ # debugger
+ @tag.pictures_attributes = { 'new_1' => { :name => 'dm-accepts_nested_attributes' } }
+ @tag.pictures.should_not be_empty
+ @tag.pictures.first.name.should == 'dm-accepts_nested_attributes'
+ @tag.save
+ @tag.pictures.first.should == Photo.first
+
+ Tag.all.size.should == 1
+ Tagging.all.size.should == 1
+ Photo.all.size.should == 1
+
+ Photo.first.name.should == 'dm-accepts_nested_attributes'
+ end
+
+ it "should allow to update an existing picture via Tag#pictures_attributes" do
+ @tag.save
+ photo = Photo.create(:name => 'dm-accepts_nested_attributes')
+ tagging = Tagging.create(:tag => @tag, :photo => photo)
+ Tag.all.size.should == 1
+ Photo.all.size.should == 1
+ Tagging.all.size.should == 1
+
+ @tag.reload
+
+ @tag.pictures_attributes = { photo.id.to_s => { :id => photo.id, :name => 'still dm-accepts_nested_attributes' } }
+ @tag.pictures.should_not be_empty
+ @tag.pictures.first.name.should == 'still dm-accepts_nested_attributes'
+ @tag.save
+
+ Tag.all.size.should == 1
+ Tagging.all.size.should == 1
+ Photo.all.size.should == 1
+
+ Photo.first.name.should == 'still dm-accepts_nested_attributes'
+ end
+
+ end
+
+ describe "every accessible has(n, :through) renamed association with :allow_destroy => false", :shared => true do
+
+ it "should not allow to delete an existing picture via Tag#pictures_attributes" do
+ @tag.save
+ photo = Photo.create(:name => 'dm-accepts_nested_attributes')
+ tagging = Tagging.create(:tag => @tag, :photo => photo)
+
+ Tag.all.size.should == 1
+ Tagging.all.size.should == 1
+ Photo.all.size.should == 1
+
+ @tag.reload
+ @tag.pictures_attributes = { '1' => { :id => photo.id, :_delete => true } }
+ @tag.save
+
+ Tag.all.size.should == 1
+ Tagging.all.size.should == 1
+ Photo.all.size.should == 1
+ end
+
+ end
+
+ describe "every accessible has(n, :through) renamed association with :allow_destroy => true", :shared => true do
+
+ it "should allow to delete an existing picture via Tag#pictures_attributes" do
+ @tag.save
+ photo = Photo.create(:name => 'dm-accepts_nested_attributes')
+ tagging = Tagging.create(:tag => @tag, :photo => photo)
+
+ Tag.all.size.should == 1
+ Tagging.all.size.should == 1
+ Photo.all.size.should == 1
+
+ @tag.reload
+ @tag.pictures_attributes = { '1' => { :id => photo.id, :_delete => true } }
+ @tag.save
+
+ Tag.all.size.should == 1
+ Tagging.all.size.should == 0
+ Photo.all.size.should == 0
+ end
+
+ end
+
+ describe "Tag.has(n, :pictures, :through => :taggings) renamed" do
+
+ describe "accepts_nested_attributes_for(:pictures)" do
+
+ before(:each) do
+ DataMapper.auto_migrate!
+ Tag.accepts_nested_attributes_for :pictures
+ @tag = Tag.new :name => 'snusnu'
+ end
+
+ it_should_behave_like "every accessible has(n, :through) renamed association with no reject_if proc"
+ it_should_behave_like "every accessible has(n, :through) renamed association with :allow_destroy => false"
+
+ end
+
+ describe "accepts_nested_attributes_for(:pictures, :allow_destroy => false)" do
+
+ before(:each) do
+ DataMapper.auto_migrate!
+ Tag.accepts_nested_attributes_for :pictures, :allow_destroy => false
+ @tag = Tag.new :name => 'snusnu'
+ end
+
+ it_should_behave_like "every accessible has(n, :through) renamed association with no reject_if proc"
+ it_should_behave_like "every accessible has(n, :through) renamed association with :allow_destroy => false"
+
+ end
+
+ describe "accepts_nested_attributes_for(:pictures, :allow_destroy = true)" do
+
+ before(:each) do
+ DataMapper.auto_migrate!
+ Tag.accepts_nested_attributes_for :pictures, :allow_destroy => true
+ @tag = Tag.new :name => 'snusnu'
+ end
+
+ it_should_behave_like "every accessible has(n, :through) renamed association with no reject_if proc"
+ it_should_behave_like "every accessible has(n, :through) renamed association with :allow_destroy => true"
+
+ end
+
+ describe "accepts_nested_attributes_for :pictures, " do
+
+ describe ":reject_if => :foo" do
+
+ before(:each) do
+ DataMapper.auto_migrate!
+ Tag.accepts_nested_attributes_for :pictures, :reject_if => :foo
+ @tag = Tag.new :name => 'snusnu'
+ end
+
+ it_should_behave_like "every accessible has(n, :through) renamed association with no reject_if proc"
+ it_should_behave_like "every accessible has(n, :through) renamed association with :allow_destroy => false"
+
+ end
+
+ describe ":reject_if => lambda { |attrs| true }" do
+
+ before(:each) do
+ DataMapper.auto_migrate!
+ Tag.accepts_nested_attributes_for :pictures, :reject_if => lambda { |attrs| true }
+ @tag = Tag.new :name => 'snusnu'
+ end
+
+ it_should_behave_like "every accessible has(n, :through) renamed association with a valid reject_if proc"
+ it_should_behave_like "every accessible has(n, :through) renamed association with :allow_destroy => false"
+
+ end
+
+ describe ":reject_if => lambda { |attrs| false }" do
+
+ before(:each) do
+ DataMapper.auto_migrate!
+ Tag.accepts_nested_attributes_for :pictures, :reject_if => lambda { |attrs| false }
+ @tag = Tag.new :name => 'snusnu'
+ end
+
+ it_should_behave_like "every accessible has(n, :through) renamed association with no reject_if proc"
+ it_should_behave_like "every accessible has(n, :through) renamed association with :allow_destroy => false"
+
+ end
+
+ end
+
+ end
+
+end
--
1.5.5.3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment