deep_cloneable 1.4.1 → 1.5.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  source 'http://rubygems.org'
2
2
 
3
- gem 'rails'
3
+ gem 'activerecord', '>= 3.1'
4
4
 
5
5
  group :development do
6
6
  gem 'jeweler'
@@ -8,4 +8,4 @@ end
8
8
 
9
9
  group :test do
10
10
  gem 'sqlite3'
11
- end
11
+ end
data/Gemfile.lock CHANGED
@@ -1,94 +1,38 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
- actionmailer (3.2.2)
5
- actionpack (= 3.2.2)
6
- mail (~> 2.4.0)
7
- actionpack (3.2.2)
8
- activemodel (= 3.2.2)
9
- activesupport (= 3.2.2)
4
+ activemodel (3.2.12)
5
+ activesupport (= 3.2.12)
10
6
  builder (~> 3.0.0)
11
- erubis (~> 2.7.0)
12
- journey (~> 1.0.1)
13
- rack (~> 1.4.0)
14
- rack-cache (~> 1.1)
15
- rack-test (~> 0.6.1)
16
- sprockets (~> 2.1.2)
17
- activemodel (3.2.2)
18
- activesupport (= 3.2.2)
19
- builder (~> 3.0.0)
20
- activerecord (3.2.2)
21
- activemodel (= 3.2.2)
22
- activesupport (= 3.2.2)
7
+ activerecord (3.2.12)
8
+ activemodel (= 3.2.12)
9
+ activesupport (= 3.2.12)
23
10
  arel (~> 3.0.2)
24
11
  tzinfo (~> 0.3.29)
25
- activeresource (3.2.2)
26
- activemodel (= 3.2.2)
27
- activesupport (= 3.2.2)
28
- activesupport (3.2.2)
12
+ activesupport (3.2.12)
29
13
  i18n (~> 0.6)
30
14
  multi_json (~> 1.0)
31
15
  arel (3.0.2)
32
- builder (3.0.0)
33
- erubis (2.7.0)
16
+ builder (3.0.4)
34
17
  git (1.2.5)
35
- hike (1.2.1)
36
- i18n (0.6.0)
37
- jeweler (1.8.3)
18
+ i18n (0.6.4)
19
+ jeweler (1.8.4)
38
20
  bundler (~> 1.0)
39
21
  git (>= 1.2.5)
40
22
  rake
41
23
  rdoc
42
- journey (1.0.3)
43
- json (1.6.6)
44
- mail (2.4.4)
45
- i18n (>= 0.4.0)
46
- mime-types (~> 1.16)
47
- treetop (~> 1.4.8)
48
- mime-types (1.18)
49
- multi_json (1.2.0)
50
- polyglot (0.3.3)
51
- rack (1.4.1)
52
- rack-cache (1.2)
53
- rack (>= 0.4)
54
- rack-ssl (1.3.2)
55
- rack
56
- rack-test (0.6.1)
57
- rack (>= 1.0)
58
- rails (3.2.2)
59
- actionmailer (= 3.2.2)
60
- actionpack (= 3.2.2)
61
- activerecord (= 3.2.2)
62
- activeresource (= 3.2.2)
63
- activesupport (= 3.2.2)
64
- bundler (~> 1.0)
65
- railties (= 3.2.2)
66
- railties (3.2.2)
67
- actionpack (= 3.2.2)
68
- activesupport (= 3.2.2)
69
- rack-ssl (~> 1.3.2)
70
- rake (>= 0.8.7)
71
- rdoc (~> 3.4)
72
- thor (~> 0.14.6)
73
- rake (0.9.2.2)
74
- rdoc (3.12)
24
+ json (1.7.7)
25
+ multi_json (1.6.1)
26
+ rake (10.0.3)
27
+ rdoc (4.0.0)
75
28
  json (~> 1.4)
76
- sprockets (2.1.2)
77
- hike (~> 1.2)
78
- rack (~> 1.0)
79
- tilt (~> 1.1, != 1.3.0)
80
- sqlite3 (1.3.5)
81
- thor (0.14.6)
82
- tilt (1.3.3)
83
- treetop (1.4.10)
84
- polyglot
85
- polyglot (>= 0.3.1)
86
- tzinfo (0.3.32)
29
+ sqlite3 (1.3.7)
30
+ tzinfo (0.3.36)
87
31
 
88
32
  PLATFORMS
89
33
  ruby
90
34
 
91
35
  DEPENDENCIES
36
+ activerecord (>= 3.1)
92
37
  jeweler
93
- rails
94
38
  sqlite3
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010 Reinier de Lange
1
+ Copyright (c) 2013 Reinier de Lange
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.rdoc CHANGED
@@ -4,6 +4,8 @@ This gem gives every ActiveRecord::Base object the possibility to do a deep clon
4
4
 
5
5
  == Requirements
6
6
 
7
+ * Ruby 1.8.7, 1.9, 2.0.0
8
+
7
9
  * Activerecord 3.1, 3.2
8
10
 
9
11
  * Rails 2.x/3.0 users, please check out the 'rails2.x-3.0' branch.
@@ -12,7 +14,7 @@ This gem gives every ActiveRecord::Base object the possibility to do a deep clon
12
14
 
13
15
  * In your Gemfile:
14
16
 
15
- gem 'deep_cloneable', '~> 1.4.0'
17
+ gem 'deep_cloneable', '~> 1.5.0'
16
18
 
17
19
  == Example
18
20
 
@@ -54,7 +56,10 @@ If this is not an option for you, it is also possible to populate the dictionary
54
56
  pirate.dup :include => :parrot do |original, kopy|
55
57
  kopy.cloned_from_id = original.id if kopy.respond_to?(:cloned_from_id)
56
58
  end
57
-
59
+
60
+ === Cloning without validations
61
+ pirate.dup :include => {:treasures => :gold_pieces}, :validate => false
62
+
58
63
  == Contributors
59
64
 
60
65
  * Michael He
@@ -64,6 +69,8 @@ If this is not an option for you, it is also possible to populate the dictionary
64
69
  * Ilya Kuzmin
65
70
  * zozi
66
71
  * fractious
72
+ * Georges Gabereau
73
+ * Christophe Belpaire
67
74
 
68
75
  == Note on Patches/Pull Requests
69
76
 
@@ -77,4 +84,4 @@ If this is not an option for you, it is also possible to populate the dictionary
77
84
 
78
85
  == Copyright
79
86
 
80
- Copyright (c) 2012 Reinier de Lange. See LICENSE for details.
87
+ Copyright (c) 2013 Reinier de Lange. See LICENSE for details.
data/Rakefile CHANGED
@@ -39,7 +39,7 @@ end
39
39
 
40
40
  task :default => :test
41
41
 
42
- require 'rake/rdoctask'
42
+ require 'rdoc/task'
43
43
  Rake::RDocTask.new do |rdoc|
44
44
  version = File.exist?('VERSION') ? File.read('VERSION') : ""
45
45
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.1
1
+ 1.5.1
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "deep_cloneable"
8
- s.version = "1.4.1"
8
+ s.version = "1.5.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Reinier de Lange"]
12
- s.date = "2012-07-23"
12
+ s.date = "2013-03-06"
13
13
  s.description = "Extends the functionality of ActiveRecord::Base#clone to perform a deep clone that includes user specified associations. "
14
14
  s.email = "r.j.delange@nedforce.nl"
15
15
  s.extra_rdoc_files = [
@@ -35,21 +35,21 @@ Gem::Specification.new do |s|
35
35
  ]
36
36
  s.homepage = "http://github.com/moiristo/deep_cloneable"
37
37
  s.require_paths = ["lib"]
38
- s.rubygems_version = "1.8.21"
38
+ s.rubygems_version = "1.8.24"
39
39
  s.summary = "This gem gives every ActiveRecord::Base object the possibility to do a deep clone."
40
40
 
41
41
  if s.respond_to? :specification_version then
42
42
  s.specification_version = 3
43
43
 
44
44
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
45
- s.add_runtime_dependency(%q<rails>, [">= 0"])
45
+ s.add_runtime_dependency(%q<activerecord>, [">= 3.1"])
46
46
  s.add_development_dependency(%q<jeweler>, [">= 0"])
47
47
  else
48
- s.add_dependency(%q<rails>, [">= 0"])
48
+ s.add_dependency(%q<activerecord>, [">= 3.1"])
49
49
  s.add_dependency(%q<jeweler>, [">= 0"])
50
50
  end
51
51
  else
52
- s.add_dependency(%q<rails>, [">= 0"])
52
+ s.add_dependency(%q<activerecord>, [">= 3.1"])
53
53
  s.add_dependency(%q<jeweler>, [">= 0"])
54
54
  end
55
55
  end
@@ -1,11 +1,9 @@
1
1
  class ActiveRecord::Base
2
2
  module DeepCloneable
3
- @@rails31 = ActiveRecord::VERSION::MAJOR >= 3 && ActiveRecord::VERSION::MINOR > 0
4
-
5
3
  # ActiveRecord::Base has its own dup method for Ruby 1.8.7. We have to
6
4
  # redefine it and put it in a module so that we can override it in a
7
5
  # module and call the original with super().
8
- if @@rails31 and !Object.respond_to? :initialize_dup
6
+ if !Object.respond_to? :initialize_dup, true
9
7
  ActiveRecord::Base.class_eval do
10
8
  module Dup
11
9
  def dup
@@ -14,57 +12,57 @@ class ActiveRecord::Base
14
12
  copy
15
13
  end
16
14
  end
17
- remove_method :dup
15
+ remove_possible_method :dup
18
16
  include Dup
19
17
  end
20
18
  end
21
19
 
22
- # clones an ActiveRecord model.
20
+ # clones an ActiveRecord model.
23
21
  # if passed the :include option, it will deep clone the given associations
24
22
  # if passed the :except option, it won't clone the given attributes
25
23
  #
26
24
  # === Usage:
27
- #
25
+ #
28
26
  # ==== Cloning one single association
29
27
  # pirate.clone :include => :mateys
30
- #
28
+ #
31
29
  # ==== Cloning multiple associations
32
30
  # pirate.clone :include => [:mateys, :treasures]
33
- #
31
+ #
34
32
  # ==== Cloning really deep
35
33
  # pirate.clone :include => {:treasures => :gold_pieces}
36
- #
34
+ #
37
35
  # ==== Cloning really deep with multiple associations
38
36
  # pirate.clone :include => [:mateys, {:treasures => :gold_pieces}]
39
37
  #
40
38
  # ==== Cloning really deep with multiple associations and a dictionary
41
39
  #
42
- # A dictionary ensures that models are not cloned multiple times when it is associated to nested models.
40
+ # A dictionary ensures that models are not cloned multiple times when it is associated to nested models.
43
41
  # When using a dictionary, ensure recurring associations are cloned first:
44
42
  #
45
- # pirate.clone :include => [:mateys, {:treasures => [:matey, :gold_pieces], :use_dictionary => true }]
43
+ # pirate.clone :include => [:mateys, {:treasures => [:matey, :gold_pieces], :use_dictionary => true }]
46
44
  #
47
45
  # If this is not an option for you, it is also possible to populate the dictionary manually in advance:
48
46
  #
49
47
  # dict = { :mateys => {} }
50
48
  # pirate.mateys.each{|m| dict[:mateys][m] = m.clone }
51
- # pirate.clone :include => [:mateys, {:treasures => [:matey, :gold_pieces], :dictionary => dict }]
52
- #
49
+ # pirate.clone :include => [:mateys, {:treasures => [:matey, :gold_pieces], :dictionary => dict }]
50
+ #
53
51
  # ==== Cloning a model without an attribute
54
52
  # pirate.clone :except => :name
55
- #
53
+ #
56
54
  # ==== Cloning a model without multiple attributes
57
55
  # pirate.clone :except => [:name, :nick_name]
58
- #
59
- # ==== Cloning a model without an attribute or nested multiple attributes
56
+ #
57
+ # ==== Cloning a model without an attribute or nested multiple attributes
60
58
  # pirate.clone :include => :parrot, :except => [:name, { :parrot => [:name] }]
61
- #
62
- define_method (@@rails31 ? :dup : :clone) do |*args, &block|
59
+ #
60
+ define_method :dup do |*args, &block|
63
61
  options = args[0] || {}
64
-
62
+
65
63
  dict = options[:dictionary]
66
64
  dict ||= {} if options.delete(:use_dictionary)
67
-
65
+
68
66
  kopy = unless dict
69
67
  super()
70
68
  else
@@ -83,40 +81,50 @@ class ActiveRecord::Base
83
81
  end
84
82
  deep_exceptions = exceptions.select{|e| e.kind_of?(Hash) }.inject({}){|m,h| m.merge(h) }
85
83
  end
86
-
84
+
87
85
  if options[:include]
88
86
  Array(options[:include]).each do |association, deep_associations|
89
87
  if (association.kind_of? Hash)
90
88
  deep_associations = association[association.keys.first]
91
89
  association = association.keys.first
92
90
  end
93
-
91
+
94
92
  opts = deep_associations.blank? ? {} : {:include => deep_associations}
95
93
  opts.merge!(:except => deep_exceptions[association]) if deep_exceptions[association]
96
94
  opts.merge!(:dictionary => dict) if dict
97
-
95
+
98
96
  association_reflection = self.class.reflect_on_association(association)
99
97
  raise AssociationNotFoundException.new("#{self.class}##{association}") if association_reflection.nil?
100
-
98
+
99
+ if options[:validate] == false
100
+ kopy.instance_eval do
101
+ # Force :validate => false on all saves.
102
+ def perform_validations(options={})
103
+ options[:validate] = false
104
+ super(options)
105
+ end
106
+ end
107
+ end
108
+
101
109
  cloned_object = case association_reflection.macro
102
110
  when :belongs_to, :has_one
103
111
  self.send(association) && self.send(association).send(__method__, opts, &block)
104
112
  when :has_many
105
- primary_key_name = (@@rails31 ? association_reflection.foreign_key : association_reflection.primary_key_name).to_s
106
-
113
+ primary_key_name = association_reflection.foreign_key.to_s
114
+
107
115
  reverse_association_name = association_reflection.klass.reflect_on_all_associations.detect do |a|
108
- a.send(@@rails31 ? :foreign_key : :primary_key_name).to_s == primary_key_name
116
+ a.foreign_key.to_s == primary_key_name
109
117
  end.try(:name)
110
-
111
- self.send(association).collect do |obj|
118
+
119
+ self.send(association).collect do |obj|
112
120
  tmp = obj.send(__method__, opts, &block)
113
- tmp.send("#{primary_key_name}=", nil)
121
+ tmp.send("#{primary_key_name}=", nil)
114
122
  tmp.send("#{reverse_association_name.to_s}=", kopy) if reverse_association_name
115
123
  tmp
116
124
  end
117
125
  when :has_and_belongs_to_many
118
- primary_key_name = (@@rails31 ? association_reflection.foreign_key : association_reflection.primary_key_name).to_s
119
-
126
+ primary_key_name = association_reflection.foreign_key.to_s
127
+
120
128
  reverse_association_name = association_reflection.klass.reflect_on_all_associations.detect do |a|
121
129
  (a.macro == :has_and_belongs_to_many) && (a.association_foreign_key.to_s == primary_key_name)
122
130
  end.try(:name)
@@ -126,16 +134,16 @@ class ActiveRecord::Base
126
134
  obj
127
135
  end
128
136
  end
129
-
137
+
130
138
  kopy.send("#{association}=", cloned_object)
131
139
  end
132
140
  end
133
141
 
134
142
  return kopy
135
143
  end
136
-
137
- class AssociationNotFoundException < StandardError; end
144
+
145
+ class AssociationNotFoundException < StandardError; end
138
146
  end
139
-
147
+
140
148
  include DeepCloneable
141
- end
149
+ end
data/test/models.rb CHANGED
@@ -1,25 +1,26 @@
1
1
  module Animal
2
2
  class Human < ActiveRecord::Base
3
3
  has_many :pigs
4
-
5
- has_many :ownerships
4
+
5
+ has_many :ownerships
6
6
  has_many :chickens, :through => :ownerships
7
7
  end
8
8
  class Pig < ActiveRecord::Base
9
9
  belongs_to :human
10
10
  end
11
-
11
+
12
12
  class Chicken < ActiveRecord::Base
13
13
  has_many :ownerships
14
14
  has_many :humans, :through => :ownerships
15
- end
16
-
15
+ end
16
+
17
17
  class Ownership < ActiveRecord::Base
18
18
  belongs_to :human
19
19
  belongs_to :chicken
20
-
20
+
21
21
  validates_uniqueness_of :chicken_id, :scope => :human_id
22
- end
22
+ end
23
+
23
24
  end
24
25
 
25
26
  class GoldPiece < ActiveRecord::Base; belongs_to :treasure end
@@ -50,4 +51,14 @@ end
50
51
 
51
52
  class Car < ActiveRecord::Base
52
53
  has_and_belongs_to_many :people
53
- end
54
+ end
55
+
56
+ class ChildWithValidation < ActiveRecord::Base
57
+ belongs_to :parent, :class_name => 'ParentWithValidation'
58
+ validates :name, :presence => true
59
+ end
60
+
61
+ class ParentWithValidation < ActiveRecord::Base
62
+ has_many :children, :class_name => 'ChildWithValidation'
63
+ validates :name, :presence => true
64
+ end
data/test/schema.rb CHANGED
@@ -6,49 +6,49 @@ ActiveRecord::Schema.define(:version => 1) do
6
6
  t.column :ship_id, :integer
7
7
  t.column :ship_type, :string
8
8
  end
9
-
9
+
10
10
  create_table :parrots, :force => true do |t|
11
11
  t.column :name, :string
12
12
  t.column :pirate_id, :integer
13
13
  end
14
-
14
+
15
15
  create_table :mateys, :force => true do |t|
16
16
  t.column :name, :string
17
17
  t.column :pirate_id, :integer
18
18
  end
19
-
19
+
20
20
  create_table :treasures, :force => true do |t|
21
21
  t.column :found_at, :string
22
22
  t.column :owner, :integer
23
- t.column :matey_id, :integer
23
+ t.column :matey_id, :integer
24
24
  end
25
-
25
+
26
26
  create_table :gold_pieces, :force => true do |t|
27
27
  t.column :treasure_id, :integer
28
28
  end
29
-
29
+
30
30
  create_table :battle_ships, :force => true do |t|
31
31
  t.column :name, :string
32
- end
33
-
32
+ end
33
+
34
34
  create_table :pigs, :force => true do |t|
35
35
  t.column :name, :string
36
36
  t.column :human_id, :integer
37
37
  end
38
-
38
+
39
39
  create_table :humen, :force => true do |t|
40
40
  t.column :name, :string
41
41
  end
42
-
42
+
43
43
  create_table :chickens, :force => true do |t|
44
44
  t.column :name, :string
45
- end
46
-
45
+ end
46
+
47
47
  create_table :ownerships, :force => true do |t|
48
48
  t.column :human_id, :integer
49
- t.column :chicken_id, :integer
49
+ t.column :chicken_id, :integer
50
50
  end
51
-
51
+
52
52
  create_table :cars, :force => true do |t|
53
53
  t.column :name, :string
54
54
  end
@@ -60,6 +60,15 @@ ActiveRecord::Schema.define(:version => 1) do
60
60
  create_table :cars_people, :id => false, :force => true do |t|
61
61
  t.column :car_id, :integer
62
62
  t.column :person_id, :integer
63
- end
64
-
63
+ end
64
+
65
+ create_table :parent_with_validations, :force => true do |t|
66
+ t.column :name, :string
67
+ end
68
+
69
+ create_table :child_with_validations, :force => true do |t|
70
+ t.column :name, :string
71
+ t.column :parent_with_validation_id, :integer
72
+ end
73
+
65
74
  end
@@ -2,10 +2,10 @@ require File.dirname(__FILE__) + '/test_helper'
2
2
 
3
3
  class TestDeepCloneable < Test::Unit::TestCase
4
4
  load_schema
5
-
6
- @@clone_method = ActiveRecord::VERSION::MAJOR >= 3 && ActiveRecord::VERSION::MINOR > 0 ? :dup : :clone
7
5
 
8
- def setup
6
+ @@clone_method = ActiveRecord::VERSION::MAJOR >= 3 && ActiveRecord::VERSION::MINOR > 0 ? :dup : :clone
7
+
8
+ def setup
9
9
  @jack = Pirate.create(:name => 'Jack Sparrow', :nick_name => 'Captain Jack', :age => 30)
10
10
  @polly = Parrot.create(:name => 'Polly', :pirate => @jack)
11
11
  @john = Matey.create(:name => 'John', :pirate => @jack)
@@ -143,30 +143,30 @@ class TestDeepCloneable < Test::Unit::TestCase
143
143
  assert dup_human.new_record?
144
144
  assert dup_human.save
145
145
  assert_equal 1, dup_human.pigs.count
146
-
146
+
147
147
  @human2 = Animal::Human.create :name => "John"
148
148
  @pig2 = @human2.pigs.create :name => 'small pig'
149
-
149
+
150
150
  dup_human_2 = @human.send(@@clone_method, :include => [:pigs])
151
151
  assert dup_human_2.new_record?
152
152
  assert dup_human_2.save
153
153
  assert_equal 1, dup_human_2.pigs.count
154
- end
155
-
154
+ end
155
+
156
156
  def test_should_dup_many_to_many_associations
157
- @human = Animal::Human.create :name => "Michael"
158
- @human2 = Animal::Human.create :name => "Jack"
157
+ @human = Animal::Human.create :name => "Michael"
158
+ @human2 = Animal::Human.create :name => "Jack"
159
159
  @chicken1 = Animal::Chicken.create :name => 'Chick1'
160
- @chicken2 = Animal::Chicken.create :name => 'Chick2'
160
+ @chicken2 = Animal::Chicken.create :name => 'Chick2'
161
161
  @human.chickens << [@chicken1, @chicken2]
162
- @human2.chickens << [@chicken1, @chicken2]
163
-
162
+ @human2.chickens << [@chicken1, @chicken2]
163
+
164
164
  dup_human = @human.send(@@clone_method, :include => :ownerships)
165
165
  assert dup_human.new_record?
166
166
  assert dup_human.save
167
- assert_equal 2, dup_human.chickens.count
168
- end
169
-
167
+ assert_equal 2, dup_human.chickens.count
168
+ end
169
+
170
170
  def test_should_dup_with_block
171
171
  dup = @jack.send(@@clone_method, :include => :parrot) do |original, kopy|
172
172
  kopy.cloned_from_id = original.id
@@ -177,7 +177,7 @@ class TestDeepCloneable < Test::Unit::TestCase
177
177
  assert_equal @jack.id, dup.cloned_from_id
178
178
  assert_equal @jack.parrot.id, dup.parrot.cloned_from_id
179
179
  end
180
-
180
+
181
181
  def test_should_dup_habtm_associations
182
182
  @person1 = Person.create :name => "Bill"
183
183
  @person2 = Person.create :name => "Ted"
@@ -201,5 +201,61 @@ class TestDeepCloneable < Test::Unit::TestCase
201
201
  assert_equal @person1.cars, dup_person.cars
202
202
  assert_equal 2, dup_person.cars.count
203
203
  end
204
-
204
+
205
+ def test_parent_validations_run_on_save_after_clone
206
+ child = ChildWithValidation.create :name => 'Jimmy'
207
+ parent = ParentWithValidation.new :children => [child]
208
+ parent.save :validate => false
209
+
210
+ dup_parent = parent.dup :include => :children
211
+
212
+ assert !dup_parent.save
213
+ assert dup_parent.new_record?
214
+ assert !dup_parent.valid?
215
+ assert dup_parent.children.first.valid?
216
+ assert_equal dup_parent.errors.messages, :name => ["can't be blank"]
217
+ end
218
+
219
+ def test_parent_validations_dont_run_on_save_after_clone
220
+ child = ChildWithValidation.create :name => 'Jimmy'
221
+ parent = ParentWithValidation.new :children => [child]
222
+ parent.save :validate => false
223
+
224
+ dup_parent = parent.dup :include => :children, :validate => false
225
+
226
+ assert dup_parent.save
227
+ assert !dup_parent.new_record?
228
+ assert !dup_parent.valid?
229
+ assert dup_parent.children.first.valid?
230
+ assert_equal dup_parent.errors.messages, :name => ["can't be blank"]
231
+ end
232
+
233
+ def test_child_validations_run_on_save_after_clone
234
+ child = ChildWithValidation.new
235
+ child.save :validate => false
236
+ parent = ParentWithValidation.create :name => 'John', :children => [child]
237
+
238
+ dup_parent = parent.dup :include => :children
239
+
240
+ assert !dup_parent.save
241
+ assert dup_parent.new_record?
242
+ assert !dup_parent.valid?
243
+ assert !dup_parent.children.first.valid?
244
+ assert_equal dup_parent.errors.messages, :children => ["is invalid"]
245
+ end
246
+
247
+ def test_child_validations_run_on_save_after_clone
248
+ child = ChildWithValidation.new
249
+ child.save :validate => false
250
+ parent = ParentWithValidation.create :name => 'John', :children => [child]
251
+
252
+ dup_parent = parent.dup :include => :children, :validate => false
253
+
254
+ assert dup_parent.save
255
+ assert !dup_parent.new_record?
256
+ assert !dup_parent.valid?
257
+ assert !dup_parent.children.first.valid?
258
+ assert_equal dup_parent.errors.messages, :children => ["is invalid"]
259
+ end
260
+
205
261
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: deep_cloneable
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.1
4
+ version: 1.5.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,16 +9,16 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-23 00:00:00.000000000 Z
12
+ date: 2013-03-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: rails
15
+ name: activerecord
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: '0'
21
+ version: '3.1'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
- version: '0'
29
+ version: '3.1'
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: jeweler
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -81,7 +81,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
81
81
  version: '0'
82
82
  segments:
83
83
  - 0
84
- hash: -3012807303620209218
84
+ hash: 250465939979745511
85
85
  required_rubygems_version: !ruby/object:Gem::Requirement
86
86
  none: false
87
87
  requirements:
@@ -90,7 +90,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
90
90
  version: '0'
91
91
  requirements: []
92
92
  rubyforge_project:
93
- rubygems_version: 1.8.21
93
+ rubygems_version: 1.8.24
94
94
  signing_key:
95
95
  specification_version: 3
96
96
  summary: This gem gives every ActiveRecord::Base object the possibility to do a deep