active_data 1.0.0 → 1.1.0

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.
Files changed (115) hide show
  1. checksums.yaml +5 -5
  2. data/.codeclimate.yml +13 -0
  3. data/.rubocop.yml +56 -0
  4. data/.rubocop_todo.yml +53 -0
  5. data/.rvmrc +1 -1
  6. data/.travis.yml +15 -2
  7. data/Appraisals +1 -1
  8. data/CHANGELOG.md +31 -0
  9. data/Guardfile +8 -8
  10. data/README.md +256 -0
  11. data/Rakefile +2 -4
  12. data/active_data.gemspec +8 -7
  13. data/gemfiles/rails.4.0.gemfile +1 -1
  14. data/gemfiles/rails.4.1.gemfile +1 -1
  15. data/gemfiles/rails.4.2.gemfile +1 -1
  16. data/gemfiles/rails.5.0.gemfile +1 -1
  17. data/gemfiles/rails.5.1.gemfile +14 -0
  18. data/lib/active_data/active_record/associations.rb +18 -13
  19. data/lib/active_data/active_record/nested_attributes.rb +8 -14
  20. data/lib/active_data/base.rb +13 -0
  21. data/lib/active_data/config.rb +4 -4
  22. data/lib/active_data/errors.rb +29 -13
  23. data/lib/active_data/extensions.rb +22 -21
  24. data/lib/active_data/model/associations/base.rb +22 -6
  25. data/lib/active_data/model/associations/embeds_any.rb +17 -0
  26. data/lib/active_data/model/associations/embeds_many.rb +29 -19
  27. data/lib/active_data/model/associations/embeds_one.rb +30 -26
  28. data/lib/active_data/model/associations/nested_attributes.rb +82 -50
  29. data/lib/active_data/model/associations/persistence_adapters/active_record/referenced_proxy.rb +31 -0
  30. data/lib/active_data/model/associations/persistence_adapters/active_record.rb +66 -0
  31. data/lib/active_data/model/associations/persistence_adapters/base.rb +53 -0
  32. data/lib/active_data/model/associations/references_any.rb +41 -0
  33. data/lib/active_data/model/associations/references_many.rb +51 -37
  34. data/lib/active_data/model/associations/references_one.rb +43 -41
  35. data/lib/active_data/model/associations/reflections/base.rb +19 -29
  36. data/lib/active_data/model/associations/reflections/embeds_any.rb +43 -0
  37. data/lib/active_data/model/associations/reflections/embeds_many.rb +3 -13
  38. data/lib/active_data/model/associations/reflections/embeds_one.rb +5 -37
  39. data/lib/active_data/model/associations/reflections/references_any.rb +62 -0
  40. data/lib/active_data/model/associations/reflections/references_many.rb +7 -7
  41. data/lib/active_data/model/associations/reflections/references_one.rb +9 -7
  42. data/lib/active_data/model/associations/reflections/singular.rb +35 -0
  43. data/lib/active_data/model/associations/validations.rb +2 -27
  44. data/lib/active_data/model/associations.rb +12 -10
  45. data/lib/active_data/model/attributes/attribute.rb +10 -10
  46. data/lib/active_data/model/attributes/base.rb +8 -7
  47. data/lib/active_data/model/attributes/localized.rb +4 -4
  48. data/lib/active_data/model/attributes/reference_many.rb +6 -8
  49. data/lib/active_data/model/attributes/reference_one.rb +17 -9
  50. data/lib/active_data/model/attributes/reflections/attribute.rb +2 -2
  51. data/lib/active_data/model/attributes/reflections/base.rb +8 -11
  52. data/lib/active_data/model/attributes/reflections/localized.rb +2 -2
  53. data/lib/active_data/model/attributes/reflections/reference_one.rb +11 -22
  54. data/lib/active_data/model/attributes/reflections/represents.rb +5 -6
  55. data/lib/active_data/model/attributes/represents.rb +6 -5
  56. data/lib/active_data/model/attributes.rb +33 -87
  57. data/lib/active_data/model/callbacks.rb +6 -7
  58. data/lib/active_data/model/conventions.rb +2 -0
  59. data/lib/active_data/model/dirty.rb +4 -4
  60. data/lib/active_data/model/lifecycle.rb +18 -20
  61. data/lib/active_data/model/localization.rb +5 -2
  62. data/lib/active_data/model/persistence.rb +2 -2
  63. data/lib/active_data/model/primary.rb +19 -14
  64. data/lib/active_data/model/representation.rb +81 -0
  65. data/lib/active_data/model/scopes.rb +22 -12
  66. data/lib/active_data/model/validations/associated.rb +3 -2
  67. data/lib/active_data/model/validations/nested.rb +6 -1
  68. data/lib/active_data/model/validations.rb +3 -3
  69. data/lib/active_data/model.rb +2 -1
  70. data/lib/active_data/undefined_class.rb +9 -0
  71. data/lib/active_data/version.rb +1 -1
  72. data/lib/active_data.rb +40 -17
  73. data/spec/lib/active_data/active_record/associations_spec.rb +107 -45
  74. data/spec/lib/active_data/active_record/nested_attributes_spec.rb +1 -2
  75. data/spec/lib/active_data/config_spec.rb +37 -15
  76. data/spec/lib/active_data/model/associations/embeds_many_spec.rb +475 -172
  77. data/spec/lib/active_data/model/associations/embeds_one_spec.rb +353 -96
  78. data/spec/lib/active_data/model/associations/nested_attributes_spec.rb +108 -12
  79. data/spec/lib/active_data/model/associations/persistence_adapters/active_record_spec.rb +58 -0
  80. data/spec/lib/active_data/model/associations/references_many_spec.rb +440 -64
  81. data/spec/lib/active_data/model/associations/references_one_spec.rb +347 -36
  82. data/spec/lib/active_data/model/associations/reflections/embeds_many_spec.rb +8 -7
  83. data/spec/lib/active_data/model/associations/reflections/embeds_one_spec.rb +7 -6
  84. data/spec/lib/active_data/model/associations/reflections/references_many_spec.rb +81 -33
  85. data/spec/lib/active_data/model/associations/reflections/references_one_spec.rb +116 -37
  86. data/spec/lib/active_data/model/associations/validations_spec.rb +27 -43
  87. data/spec/lib/active_data/model/associations_spec.rb +34 -25
  88. data/spec/lib/active_data/model/attributes/attribute_spec.rb +26 -23
  89. data/spec/lib/active_data/model/attributes/base_spec.rb +5 -6
  90. data/spec/lib/active_data/model/attributes/collection_spec.rb +7 -8
  91. data/spec/lib/active_data/model/attributes/dictionary_spec.rb +40 -33
  92. data/spec/lib/active_data/model/attributes/localized_spec.rb +27 -28
  93. data/spec/lib/active_data/model/attributes/reflections/attribute_spec.rb +6 -6
  94. data/spec/lib/active_data/model/attributes/represents_spec.rb +10 -78
  95. data/spec/lib/active_data/model/attributes_spec.rb +150 -45
  96. data/spec/lib/active_data/model/callbacks_spec.rb +69 -70
  97. data/spec/lib/active_data/model/conventions_spec.rb +0 -1
  98. data/spec/lib/active_data/model/dirty_spec.rb +22 -13
  99. data/spec/lib/active_data/model/lifecycle_spec.rb +49 -23
  100. data/spec/lib/active_data/model/persistence_spec.rb +5 -6
  101. data/spec/lib/active_data/model/representation_spec.rb +126 -0
  102. data/spec/lib/active_data/model/scopes_spec.rb +1 -3
  103. data/spec/lib/active_data/model/typecasting_spec.rb +6 -5
  104. data/spec/lib/active_data/model/validations/associated_spec.rb +26 -18
  105. data/spec/lib/active_data/model/validations/nested_spec.rb +89 -18
  106. data/spec/lib/active_data/model_spec.rb +1 -2
  107. data/spec/lib/active_data_spec.rb +0 -1
  108. data/spec/shared/nested_attribute_examples.rb +332 -0
  109. data/spec/spec_helper.rb +3 -0
  110. data/spec/support/model_helpers.rb +2 -2
  111. data/spec/support/muffle_helper.rb +7 -0
  112. metadata +52 -18
  113. data/lib/active_data/model/associations/collection/referenced.rb +0 -26
  114. data/lib/active_data/model/associations/reflections/reference_reflection.rb +0 -45
  115. data/spec/lib/active_data/model/nested_attributes.rb +0 -202
@@ -3,21 +3,15 @@ module ActiveData
3
3
  module NestedAttributes
4
4
  extend ActiveSupport::Concern
5
5
 
6
- included do
7
- singleton_class.alias_method_chain :accepts_nested_attributes_for, :active_data
8
- end
9
-
10
- module ClassMethods
11
- def accepts_nested_attributes_for_with_active_data *attr_names
12
- options = attr_names.extract_options!
13
- active_data_associations, active_record_association = attr_names.partition do |association_name|
14
- reflect_on_association(association_name).is_a?(ActiveData::Model::Associations::Reflections::Base)
15
- end
16
-
17
- ActiveData::Model::Associations::NestedAttributes::NestedAttributesMethods
18
- .accepts_nested_attributes_for self, *active_data_associations, options.dup
19
- accepts_nested_attributes_for_without_active_data *active_record_association, options.dup
6
+ def accepts_nested_attributes_for(*attr_names)
7
+ options = attr_names.extract_options!
8
+ active_data_associations, active_record_association = attr_names.partition do |association_name|
9
+ reflect_on_association(association_name).is_a?(ActiveData::Model::Associations::Reflections::Base)
20
10
  end
11
+
12
+ ActiveData::Model::Associations::NestedAttributes::NestedAttributesMethods
13
+ .accepts_nested_attributes_for(self, *active_data_associations, options.dup)
14
+ super(*active_record_association, options.dup)
21
15
  end
22
16
  end
23
17
  end
@@ -0,0 +1,13 @@
1
+ require 'active_data/model'
2
+ require 'active_data/model/primary'
3
+ require 'active_data/model/lifecycle'
4
+ require 'active_data/model/associations'
5
+
6
+ module ActiveData
7
+ class Base
8
+ include ActiveData::Model
9
+ include ActiveData::Model::Primary
10
+ include ActiveData::Model::Lifecycle
11
+ include ActiveData::Model::Associations
12
+ end
13
+ end
@@ -18,22 +18,22 @@ module ActiveData
18
18
  @_typecasters = {}
19
19
  end
20
20
 
21
- def normalizer name, &block
21
+ def normalizer(name, &block)
22
22
  if block
23
23
  _normalizers[name.to_sym] = block
24
24
  else
25
- _normalizers[name.to_sym] or raise NormalizerMissing.new(name)
25
+ _normalizers[name.to_sym] or raise NormalizerMissing, name
26
26
  end
27
27
  end
28
28
 
29
- def typecaster *classes, &block
29
+ def typecaster(*classes, &block)
30
30
  classes = classes.flatten
31
31
  if block
32
32
  _typecasters[classes.first.to_s.camelize] = block
33
33
  else
34
34
  _typecasters[classes.detect do |klass|
35
35
  _typecasters[klass.to_s.camelize]
36
- end.to_s.camelize] or raise TypecasterMissing.new(*classes)
36
+ end.to_s.camelize] or raise TypecasterMissing, classes
37
37
  end
38
38
  end
39
39
  end
@@ -11,7 +11,7 @@ module ActiveData
11
11
 
12
12
  def initialize(model)
13
13
  @model = model
14
- errors = @model.errors.full_messages.join(", ")
14
+ errors = @model.errors.full_messages.join(', ')
15
15
  super(I18n.t(:"#{@model.class.i18n_scope}.errors.messages.model_invalid", errors: errors, default: :'errors.messages.model_invalid'))
16
16
  end
17
17
  end
@@ -32,13 +32,13 @@ module ActiveData
32
32
  end
33
33
 
34
34
  class AssociationTypeMismatch < ActiveDataError
35
- def initialize expected, got
35
+ def initialize(expected, got)
36
36
  super "Expected `#{expected}` (##{expected.object_id}), but got `#{got}` (##{got.object_id})"
37
37
  end
38
38
  end
39
39
 
40
40
  class ObjectNotFound < ActiveDataError
41
- def initialize object, association_name, record_id
41
+ def initialize(object, association_name, record_id)
42
42
  message = "Couldn't find #{object.class.reflect_on_association(association_name).klass.name}" \
43
43
  "with #{object.respond_to?(:_primary_name) ? object._primary_name : 'id'} = #{record_id} for #{object.inspect}"
44
44
  super message
@@ -46,14 +46,14 @@ module ActiveData
46
46
  end
47
47
 
48
48
  class TooManyObjects < ActiveDataError
49
- def initialize limit, actual_size
49
+ def initialize(limit, actual_size)
50
50
  super "Maximum #{limit} objects are allowed. Got #{actual_size} objects instead."
51
51
  end
52
52
  end
53
53
 
54
54
  class UndefinedPrimaryAttribute < ActiveDataError
55
- def initialize klass, association_name
56
- super <<-EOS
55
+ def initialize(klass, association_name)
56
+ super <<-MESSAGE
57
57
  Undefined primary attribute for `#{association_name}` in #{klass}.
58
58
  It is required for embeds_many nested attributes proper operation.
59
59
  You can define this association as:
@@ -61,33 +61,49 @@ You can define this association as:
61
61
  embeds_many :#{association_name} do
62
62
  primary :attribute_name
63
63
  end
64
- EOS
64
+ MESSAGE
65
65
  end
66
66
  end
67
67
 
68
68
  class NormalizerMissing < NoMethodError
69
- def initialize name
70
- super <<-EOS
69
+ def initialize(name)
70
+ super <<-MESSAGE
71
71
  Could not find normalizer `:#{name}`
72
72
  You can define it with:
73
73
 
74
74
  ActiveData.normalizer(:#{name}) do |value, options|
75
75
  # do some staff with value and options
76
76
  end
77
- EOS
77
+ MESSAGE
78
78
  end
79
79
  end
80
80
 
81
81
  class TypecasterMissing < NoMethodError
82
- def initialize *classes
83
- super <<-EOS
82
+ def initialize(*classes)
83
+ classes = classes.flatten
84
+ super <<-MESSAGE
84
85
  Could not find typecaster for #{classes}
85
86
  You can define it with:
86
87
 
87
88
  ActiveData.typecaster('#{classes.first}') do |value|
88
89
  # do some staff with value and options
89
90
  end
90
- EOS
91
+ MESSAGE
92
+ end
93
+ end
94
+
95
+ class PersistenceAdapterMissing < NoMethodError
96
+ def initialize(data_source)
97
+ super <<-MESSAGE
98
+ Could not find persistence adapter for #{data_source}
99
+ You can define it with:
100
+
101
+ class #{data_source}
102
+ def self.active_data_persistence_adapter
103
+ #{data_source}ActiveDataPersistenceAdapter
104
+ end
105
+ end
106
+ MESSAGE
91
107
  end
92
108
  end
93
109
  end
@@ -1,33 +1,34 @@
1
- unless defined?(Boolean)
2
- class Boolean; end
3
- end
1
+ class Boolean; end unless defined?(Boolean)
4
2
 
5
3
  begin
6
4
  require 'uuidtools'
7
5
  rescue LoadError
6
+ nil
8
7
  else
9
- class ActiveData::UUID < UUIDTools::UUID
10
- def as_json *_
11
- to_s
12
- end
8
+ module ActiveData
9
+ class UUID < UUIDTools::UUID
10
+ def as_json(*_)
11
+ to_s
12
+ end
13
13
 
14
- def to_param
15
- to_s
16
- end
14
+ def to_param
15
+ to_s
16
+ end
17
17
 
18
- def self.parse_string value
19
- return nil if value.length == 0
20
- if value.length == 36
21
- parse value
22
- elsif value.length == 32
23
- parse_hexdigest value
24
- else
25
- parse_raw value
18
+ def self.parse_string(value)
19
+ return nil if value.length.zero?
20
+ if value.length == 36
21
+ parse value
22
+ elsif value.length == 32
23
+ parse_hexdigest value
24
+ else
25
+ parse_raw value
26
+ end
26
27
  end
27
- end
28
28
 
29
- def inspect
30
- "#<ActiveData::UUID:#{to_s}>"
29
+ def inspect
30
+ "#<ActiveData::UUID:#{self}>"
31
+ end
31
32
  end
32
33
  end
33
34
  end
@@ -5,8 +5,9 @@ module ActiveData
5
5
  attr_accessor :owner, :reflection
6
6
  delegate :macro, :collection?, to: :reflection
7
7
 
8
- def initialize owner, reflection
9
- @owner, @reflection = owner, reflection
8
+ def initialize(owner, reflection)
9
+ @owner = owner
10
+ @reflection = reflection
10
11
  @evar_loaded = owner.persisted?
11
12
  reset
12
13
  end
@@ -43,9 +44,24 @@ module ActiveData
43
44
  apply_changes or raise ActiveData::AssociationChangesNotApplied
44
45
  end
45
46
 
46
- def transaction &block
47
- data = Marshal.load(Marshal.dump(read_source))
48
- block.call
47
+ def callback(name, object)
48
+ evaluator = reflection.options[name]
49
+ return true unless evaluator
50
+
51
+ if evaluator.is_a?(Proc)
52
+ if evaluator.arity == 1
53
+ owner.instance_exec(object, &evaluator)
54
+ else
55
+ evaluator.call(owner, object)
56
+ end
57
+ else
58
+ owner.send(evaluator, object)
59
+ end
60
+ end
61
+
62
+ def transaction
63
+ data = read_source.deep_dup
64
+ yield
49
65
  rescue StandardError => e
50
66
  write_source data
51
67
  reload
@@ -62,7 +78,7 @@ module ActiveData
62
78
  reflection.read_source owner
63
79
  end
64
80
 
65
- def write_source value
81
+ def write_source(value)
66
82
  reflection.write_source owner, value
67
83
  end
68
84
 
@@ -0,0 +1,17 @@
1
+ module ActiveData
2
+ module Model
3
+ module Associations
4
+ class EmbedsAny < Base
5
+ private
6
+
7
+ def build_object(attributes)
8
+ reflection.klass.new(attributes)
9
+ end
10
+
11
+ def embed_object(object)
12
+ object.instance_variable_set(:@embedder, owner)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,16 +1,16 @@
1
1
  module ActiveData
2
2
  module Model
3
3
  module Associations
4
- class EmbedsMany < Base
5
- def build attributes = {}
6
- push_object(reflection.klass.new(attributes))
4
+ class EmbedsMany < EmbedsAny
5
+ def build(attributes = {})
6
+ push_object(build_object(attributes))
7
7
  end
8
8
 
9
- def create attributes = {}
9
+ def create(attributes = {})
10
10
  build(attributes).tap(&:save)
11
11
  end
12
12
 
13
- def create! attributes = {}
13
+ def create!(attributes = {})
14
14
  build(attributes).tap(&:save!)
15
15
  end
16
16
 
@@ -27,7 +27,7 @@ module ActiveData
27
27
  result
28
28
  end
29
29
 
30
- def target= objects
30
+ def target=(objects)
31
31
  objects.each { |object| setup_performers! object }
32
32
  loaded!
33
33
  @target = objects
@@ -47,7 +47,7 @@ module ActiveData
47
47
  else
48
48
  default.map do |attributes|
49
49
  reflection.klass.with_sanitize(false) do
50
- reflection.klass.new(attributes)
50
+ build_object(attributes)
51
51
  end
52
52
  end
53
53
  end
@@ -63,16 +63,20 @@ module ActiveData
63
63
  end
64
64
 
65
65
  def clear
66
- transaction { target.all?(&:destroy!) } rescue ActiveData::ObjectNotDestroyed
66
+ begin
67
+ transaction { target.all?(&:destroy!) }
68
+ rescue ActiveData::ObjectNotDestroyed
69
+ nil
70
+ end
67
71
  reload.empty?
68
72
  end
69
73
 
70
- def reader force_reload = false
74
+ def reader(force_reload = false)
71
75
  reload if force_reload
72
76
  @proxy ||= Collection::Embedded.new self
73
77
  end
74
78
 
75
- def replace objects
79
+ def replace(objects)
76
80
  transaction do
77
81
  clear
78
82
  append(objects) or raise ActiveData::AssociationChangesNotApplied
@@ -80,7 +84,7 @@ module ActiveData
80
84
  end
81
85
  alias_method :writer, :replace
82
86
 
83
- def concat *objects
87
+ def concat(*objects)
84
88
  append objects.flatten
85
89
  end
86
90
 
@@ -90,7 +94,7 @@ module ActiveData
90
94
  super || []
91
95
  end
92
96
 
93
- def append objects
97
+ def append(objects)
94
98
  objects.each do |object|
95
99
  raise AssociationTypeMismatch.new(reflection.klass, object.class) unless object && object.is_a?(reflection.klass)
96
100
  push_object object
@@ -99,19 +103,23 @@ module ActiveData
99
103
  result && target
100
104
  end
101
105
 
102
- def push_object object
106
+ def push_object(object)
103
107
  setup_performers! object
104
108
  target[target.size] = object
109
+ object
105
110
  end
106
111
 
107
- def setup_performers! object
112
+ def setup_performers!(object)
113
+ embed_object(object)
114
+ callback(:before_add, object)
115
+
108
116
  association = self
109
117
 
110
118
  object.define_create do
111
119
  source = association.send(:read_source)
112
- index = association.target.select do |one|
113
- one.persisted? || one === self
114
- end.index { |one| one === self }
120
+ index = association.target
121
+ .select { |one| one.persisted? || one.equal?(self) }
122
+ .index { |one| one.equal?(self) }
115
123
 
116
124
  source.insert(index, attributes)
117
125
  association.send(:write_source, source)
@@ -119,7 +127,7 @@ module ActiveData
119
127
 
120
128
  object.define_update do
121
129
  source = association.send(:read_source)
122
- index = association.target.select(&:persisted?).index { |one| one === self }
130
+ index = association.target.select(&:persisted?).index { |one| one.equal?(self) }
123
131
 
124
132
  source[index] = attributes
125
133
  association.send(:write_source, source)
@@ -127,11 +135,13 @@ module ActiveData
127
135
 
128
136
  object.define_destroy do
129
137
  source = association.send(:read_source)
130
- index = association.target.select(&:persisted?).index { |one| one === self }
138
+ index = association.target.select(&:persisted?).index { |one| one.equal?(self) }
131
139
 
132
140
  source.delete_at(index) if index
133
141
  association.send(:write_source, source)
134
142
  end
143
+
144
+ callback(:after_add, object)
135
145
  end
136
146
  end
137
147
  end
@@ -1,23 +1,21 @@
1
1
  module ActiveData
2
2
  module Model
3
3
  module Associations
4
- class EmbedsOne < Base
5
- def build attributes = {}
6
- self.target = reflection.klass.new(attributes)
4
+ class EmbedsOne < EmbedsAny
5
+ attr_reader :destroyed
6
+
7
+ def build(attributes = {})
8
+ self.target = build_object(attributes)
7
9
  end
8
10
 
9
- def create attributes = {}
11
+ def create(attributes = {})
10
12
  build(attributes).tap(&:save)
11
13
  end
12
14
 
13
- def create! attributes = {}
15
+ def create!(attributes = {})
14
16
  build(attributes).tap(&:save!)
15
17
  end
16
18
 
17
- def destroyed
18
- @destroyed
19
- end
20
-
21
19
  def apply_changes
22
20
  if target
23
21
  if target.destroyed? || target.marked_for_destruction?
@@ -31,10 +29,14 @@ module ActiveData
31
29
  end
32
30
  end
33
31
 
34
- def target= object
35
- setup_performers! object if object
32
+ def target=(object)
33
+ if object
34
+ callback(:before_add, object)
35
+ setup_performers! object
36
+ end
36
37
  loaded!
37
38
  @target = object
39
+ callback(:after_add, object) if object
38
40
  end
39
41
 
40
42
  def load_target
@@ -43,20 +45,21 @@ module ActiveData
43
45
  end
44
46
 
45
47
  def default
46
- unless evar_loaded?
47
- default = reflection.default(owner)
48
- if default
49
- object = if default.is_a?(reflection.klass)
50
- default
51
- else
52
- reflection.klass.with_sanitize(false) do
53
- reflection.klass.new(default)
54
- end
55
- end
56
- object.send(:clear_changes_information) if reflection.klass.dirty?
57
- object
48
+ return if evar_loaded?
49
+
50
+ default = reflection.default(owner)
51
+
52
+ return unless default
53
+
54
+ object = if default.is_a?(reflection.klass)
55
+ default
56
+ else
57
+ reflection.klass.with_sanitize(false) do
58
+ build_object(default)
58
59
  end
59
60
  end
61
+ object.send(:clear_changes_information) if reflection.klass.dirty?
62
+ object
60
63
  end
61
64
 
62
65
  def clear
@@ -64,12 +67,12 @@ module ActiveData
64
67
  reload.nil?
65
68
  end
66
69
 
67
- def reader force_reload = false
70
+ def reader(force_reload = false)
68
71
  reload if force_reload
69
72
  target
70
73
  end
71
74
 
72
- def replace object
75
+ def replace(object)
73
76
  if object
74
77
  raise AssociationTypeMismatch.new(reflection.klass, object.class) unless object.is_a?(reflection.klass)
75
78
  transaction do
@@ -87,7 +90,8 @@ module ActiveData
87
90
 
88
91
  private
89
92
 
90
- def setup_performers! object
93
+ def setup_performers!(object)
94
+ embed_object(object)
91
95
  association = self
92
96
 
93
97
  object.define_save do