Skip to content
Browse files

add test for habtm associations, fix dup for habtm associations

  • Loading branch information...
1 parent 8e1bbbb commit 79f2d5a129df312b1c05d64c6119033057dc6bef @moiristo committed Apr 27, 2012
Showing with 103 additions and 49 deletions.
  1. +1 −0 README.rdoc
  2. +14 −2 lib/deep_cloneable.rb
  3. +53 −0 test/models.rb
  4. +14 −1 test/schema.rb
  5. +20 −0 test/test_deep_cloneable.rb
  6. +1 −46 test/test_helper.rb
View
1 README.rdoc
@@ -62,6 +62,7 @@ If this is not an option for you, it is also possible to populate the dictionary
* Mart Karu
* Rolf Timmermans
* Ilya Kuzmin
+* zozi
== Note on Patches/Pull Requests
View
16 lib/deep_cloneable.rb
@@ -101,7 +101,7 @@ def dup
cloned_object = case association_reflection.macro
when :belongs_to, :has_one
self.send(association) && self.send(association).send(__method__, opts, &block)
- when :has_many, :has_and_belongs_to_many
+ when :has_many
primary_key_name = (@@rails31 ? association_reflection.foreign_key : association_reflection.primary_key_name).to_s
reverse_association_name = association_reflection.klass.reflect_on_all_associations.detect do |a|
@@ -114,7 +114,19 @@ def dup
tmp.send("#{reverse_association_name.to_s}=", kopy) if reverse_association_name
tmp
end
- end
+ when :has_and_belongs_to_many
+ primary_key_name = (@@rails31 ? association_reflection.foreign_key : association_reflection.primary_key_name).to_s
+
+ reverse_association_name = association_reflection.klass.reflect_on_all_associations.detect do |a|
+ (a.macro == :has_and_belongs_to_many) && (a.association_foreign_key.to_s == primary_key_name)
+ end.try(:name)
+
+ self.send(association).collect do |obj|
+ obj.send(reverse_association_name) << kopy
+ obj
+ end
+ end
+
kopy.send("#{association}=", cloned_object)
end
end
View
53 test/models.rb
@@ -0,0 +1,53 @@
+module Animal
+ class Human < ActiveRecord::Base
+ has_many :pigs
+
+ has_many :ownerships
+ has_many :chickens, :through => :ownerships
+ end
+ class Pig < ActiveRecord::Base
+ belongs_to :human
+ end
+
+ class Chicken < ActiveRecord::Base
+ has_many :ownerships
+ has_many :humans, :through => :ownerships
+ end
+
+ class Ownership < ActiveRecord::Base
+ belongs_to :human
+ belongs_to :chicken
+
+ validates_uniqueness_of :chicken_id, :scope => :human_id
+ end
+end
+
+class GoldPiece < ActiveRecord::Base; belongs_to :treasure end
+class Matey < ActiveRecord::Base; belongs_to :pirate end
+class Parrot < ActiveRecord::Base; belongs_to :pirate; attr_accessor :cloned_from_id end
+class BattleShip < ActiveRecord::Base; has_many :pirates, :as => :ship end
+
+class Pirate < ActiveRecord::Base
+ belongs_to :ship, :polymorphic => true
+
+ has_many :mateys
+ has_many :treasures, :foreign_key => 'owner'
+ has_many :gold_pieces, :through => :treasures
+ has_one :parrot
+
+ attr_accessor :cloned_from_id
+end
+
+class Treasure < ActiveRecord::Base
+ belongs_to :pirate, :foreign_key => :owner
+ belongs_to :matey
+ has_many :gold_pieces
+end
+
+class Person < ActiveRecord::Base
+ has_and_belongs_to_many :cars
+end
+
+class Car < ActiveRecord::Base
+ has_and_belongs_to_many :people
+end
View
15 test/schema.rb
@@ -47,6 +47,19 @@
create_table :ownerships, :force => true do |t|
t.column :human_id, :integer
t.column :chicken_id, :integer
- end
+ end
+
+ create_table :cars, :force => true do |t|
+ t.column :name, :string
+ end
+
+ create_table :people, :force => true do |t|
+ t.column :name, :string
+ end
+
+ create_table :cars_people, :id => false, :force => true do |t|
+ t.column :car_id, :integer
+ t.column :person_id, :integer
+ end
end
View
20 test/test_deep_cloneable.rb
@@ -159,4 +159,24 @@ def test_should_dup_with_block
assert_equal @jack.id, dup.cloned_from_id
assert_equal @jack.parrot.id, dup.parrot.cloned_from_id
end
+
+ def test_should_dup_habtm_associations
+ @person1 = Person.create :name => "Bill"
+ @person2 = Person.create :name => "Ted"
+ @car1 = Car.create :name => 'Mustang'
+ @car2 = Car.create :name => 'Camaro'
+ @person1.cars << [@car1, @car2]
+ @person2.cars << [@car1, @car2]
+
+ dup_person = @person1.dup :include => :cars
+ assert dup_person.save
+
+ # did NOT dup the Car instances
+ assert_equal 2, Car.all.count
+
+ # did dup the correct join table rows
+ assert_equal dup_person.cars, @person1.cars
+ assert_equal 2, dup_person.cars.count
+ end
+
end
View
47 test/test_helper.rb
@@ -7,52 +7,7 @@
require 'active_record'
require File.dirname(__FILE__) + '/../init.rb'
-
-module Animal
- class Human < ActiveRecord::Base
- has_many :pigs
-
- has_many :ownerships
- has_many :chickens, :through => :ownerships
- end
- class Pig < ActiveRecord::Base
- belongs_to :human
- end
-
- class Chicken < ActiveRecord::Base
- has_many :ownerships
- has_many :humans, :through => :ownerships
- end
-
- class Ownership < ActiveRecord::Base
- belongs_to :human
- belongs_to :chicken
-
- validates_uniqueness_of :chicken_id, :scope => :human_id
- end
-end
-
-class GoldPiece < ActiveRecord::Base; belongs_to :treasure end
-class Matey < ActiveRecord::Base; belongs_to :pirate end
-class Parrot < ActiveRecord::Base; belongs_to :pirate; attr_accessor :cloned_from_id end
-class BattleShip < ActiveRecord::Base; has_many :pirates, :as => :ship end
-
-class Pirate < ActiveRecord::Base
- belongs_to :ship, :polymorphic => true
-
- has_many :mateys
- has_many :treasures, :foreign_key => 'owner'
- has_many :gold_pieces, :through => :treasures
- has_one :parrot
-
- attr_accessor :cloned_from_id
-end
-
-class Treasure < ActiveRecord::Base
- belongs_to :pirate, :foreign_key => :owner
- belongs_to :matey
- has_many :gold_pieces
-end
+require 'models'
def load_schema
config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))

0 comments on commit 79f2d5a

Please sign in to comment.
Something went wrong with that request. Please try again.