deep_cloneable 1.4.1 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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