active_data 0.1.0 → 0.2.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.
- data/.rspec +1 -0
- data/.travis.yml +1 -1
- data/Gemfile +5 -7
- data/Guardfile +8 -3
- data/active_data.gemspec +2 -2
- data/lib/active_data/attributes/base.rb +10 -5
- data/lib/active_data/attributes/localized.rb +1 -1
- data/lib/active_data/model/associations/{many.rb → association.rb} +9 -3
- data/lib/active_data/model/associations/embeds_many.rb +33 -0
- data/lib/active_data/model/associations/embeds_one.rb +30 -0
- data/lib/active_data/model/associations.rb +19 -22
- data/lib/active_data/model/attributable.rb +35 -29
- data/lib/active_data/model/collectionizable.rb +13 -12
- data/lib/active_data/model/extensions/array.rb +3 -3
- data/lib/active_data/model/extensions/big_decimal.rb +2 -2
- data/lib/active_data/model/extensions/date.rb +1 -8
- data/lib/active_data/model/extensions/date_time.rb +17 -0
- data/lib/active_data/model/extensions/float.rb +1 -1
- data/lib/active_data/model/extensions/hash.rb +1 -1
- data/lib/active_data/model/extensions/integer.rb +1 -1
- data/lib/active_data/model/extensions/localized.rb +2 -2
- data/lib/active_data/model/extensions/object.rb +17 -0
- data/lib/active_data/model/extensions/time.rb +17 -0
- data/lib/active_data/model/localizable.rb +3 -3
- data/lib/active_data/model/nested_attributes.rb +10 -4
- data/lib/active_data/model.rb +17 -11
- data/lib/active_data/validations/associated.rb +17 -0
- data/lib/active_data/validations.rb +7 -0
- data/lib/active_data/version.rb +1 -1
- data/lib/active_data.rb +1 -1
- data/spec/lib/active_data/model/associations/embeds_many_spec.rb +93 -0
- data/spec/lib/active_data/model/associations/embeds_one_spec.rb +57 -0
- data/spec/lib/active_data/model/attributable_spec.rb +118 -2
- data/spec/lib/active_data/model/attributes/localized_spec.rb +1 -0
- data/spec/lib/active_data/model/collectionizable_spec.rb +41 -15
- data/spec/lib/active_data/model/nested_attributes_spec.rb +47 -26
- data/spec/lib/active_data/model/type_cast_spec.rb +31 -3
- data/spec/lib/active_data/model_spec.rb +26 -7
- data/spec/lib/active_data/validations/associated_spec.rb +88 -0
- metadata +27 -16
- data/spec/lib/active_data/model/associations_spec.rb +0 -35
data/.rspec
CHANGED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -3,12 +3,10 @@ source 'https://rubygems.org'
|
|
3
3
|
# Specify your gem's dependencies in active_data.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
+
gem 'timecop'
|
7
|
+
|
6
8
|
gem 'guard'
|
7
9
|
gem 'guard-rspec'
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
else
|
12
|
-
gem 'rb-inotify'
|
13
|
-
gem 'libnotify'
|
14
|
-
end
|
10
|
+
gem 'rb-inotify', require: false
|
11
|
+
gem 'rb-fsevent', require: false
|
12
|
+
gem 'rb-fchange', require: false
|
data/Guardfile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# A sample Guardfile
|
2
2
|
# More info at https://github.com/guard/guard#readme
|
3
3
|
|
4
|
-
guard
|
4
|
+
guard :rspec do
|
5
5
|
watch(%r{^spec/.+_spec\.rb$})
|
6
6
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
7
7
|
watch('spec/spec_helper.rb') { "spec" }
|
@@ -13,7 +13,12 @@ guard 'rspec', :version => 2 do
|
|
13
13
|
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
14
14
|
watch('config/routes.rb') { "spec/routing" }
|
15
15
|
watch('app/controllers/application_controller.rb') { "spec/controllers" }
|
16
|
-
|
17
|
-
|
16
|
+
|
17
|
+
# Capybara features specs
|
18
|
+
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
|
19
|
+
|
20
|
+
# Turnip features and steps
|
21
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
22
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
|
18
23
|
end
|
19
24
|
|
data/active_data.gemspec
CHANGED
@@ -17,6 +17,6 @@ Gem::Specification.new do |gem|
|
|
17
17
|
|
18
18
|
gem.add_development_dependency "rake"
|
19
19
|
gem.add_development_dependency "rspec"
|
20
|
-
gem.add_runtime_dependency "activesupport"
|
21
|
-
gem.add_runtime_dependency "activemodel"
|
20
|
+
gem.add_runtime_dependency "activesupport", "~> 3.0"
|
21
|
+
gem.add_runtime_dependency "activemodel", "~> 3.0"
|
22
22
|
end
|
@@ -10,7 +10,7 @@ module ActiveData
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def type
|
13
|
-
@type ||= options[:type] ||
|
13
|
+
@type ||= options[:type] || Object
|
14
14
|
end
|
15
15
|
|
16
16
|
def values
|
@@ -18,15 +18,20 @@ module ActiveData
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def default
|
21
|
-
@default ||= options[:default]
|
21
|
+
@default ||= @options[:default]
|
22
|
+
end
|
23
|
+
|
24
|
+
def default_blank?
|
25
|
+
@default_blank ||= !!@options[:default_blank]
|
22
26
|
end
|
23
27
|
|
24
28
|
def default_value instance
|
25
|
-
default.call instance
|
29
|
+
default.respond_to?(:call) ? default.call(instance) : default unless default.nil?
|
26
30
|
end
|
27
31
|
|
28
32
|
def type_cast value
|
29
|
-
|
33
|
+
return value if value.instance_of?(type)
|
34
|
+
type.active_data_type_cast(value)
|
30
35
|
end
|
31
36
|
|
32
37
|
def generate_instance_methods context
|
@@ -49,7 +54,7 @@ module ActiveData
|
|
49
54
|
EOS
|
50
55
|
end
|
51
56
|
|
52
|
-
def
|
57
|
+
def generate_class_methods context
|
53
58
|
if values
|
54
59
|
context.class_eval <<-EOS
|
55
60
|
def #{name}_values
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module ActiveData
|
2
2
|
module Model
|
3
3
|
module Associations
|
4
|
-
class
|
4
|
+
class Association
|
5
5
|
attr_reader :name, :klass, :options
|
6
6
|
|
7
7
|
def initialize name, options = {}
|
@@ -14,10 +14,16 @@ module ActiveData
|
|
14
14
|
klass.to_s
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
18
|
-
|
17
|
+
def define_accessor klass
|
18
|
+
define_reader klass
|
19
|
+
define_writer klass
|
19
20
|
end
|
20
21
|
|
22
|
+
def define_reader klass
|
23
|
+
end
|
24
|
+
|
25
|
+
def define_writer klass
|
26
|
+
end
|
21
27
|
end
|
22
28
|
end
|
23
29
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module ActiveData
|
2
|
+
module Model
|
3
|
+
module Associations
|
4
|
+
class EmbedsMany < Association
|
5
|
+
|
6
|
+
def collection?
|
7
|
+
true
|
8
|
+
end
|
9
|
+
|
10
|
+
def define_reader target
|
11
|
+
target.class_eval <<-EOS
|
12
|
+
def #{name}
|
13
|
+
@#{name} ||= begin
|
14
|
+
association = self.class.reflect_on_association('#{name}')
|
15
|
+
association.klass.collection
|
16
|
+
end
|
17
|
+
end
|
18
|
+
EOS
|
19
|
+
end
|
20
|
+
|
21
|
+
def define_writer target
|
22
|
+
target.class_eval <<-EOS
|
23
|
+
def #{name}= value
|
24
|
+
association = self.class.reflect_on_association('#{name}')
|
25
|
+
@#{name} = association.klass.collection(value)
|
26
|
+
end
|
27
|
+
EOS
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module ActiveData
|
2
|
+
module Model
|
3
|
+
module Associations
|
4
|
+
class EmbedsOne < Association
|
5
|
+
|
6
|
+
def collection?
|
7
|
+
false
|
8
|
+
end
|
9
|
+
|
10
|
+
def define_reader target
|
11
|
+
target.class_eval <<-EOS
|
12
|
+
def #{name}
|
13
|
+
@#{name}
|
14
|
+
end
|
15
|
+
EOS
|
16
|
+
end
|
17
|
+
|
18
|
+
def define_writer target
|
19
|
+
target.class_eval <<-EOS
|
20
|
+
def #{name}= value
|
21
|
+
association = self.class.reflect_on_association('#{name}')
|
22
|
+
@#{name} = association.klass.instantiate(value) if value
|
23
|
+
end
|
24
|
+
EOS
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
require 'active_data/model/associations/
|
1
|
+
require 'active_data/model/associations/association'
|
2
|
+
require 'active_data/model/associations/embeds_many'
|
3
|
+
require 'active_data/model/associations/embeds_one'
|
2
4
|
|
3
5
|
module ActiveData
|
4
6
|
module Model
|
@@ -6,14 +8,22 @@ module ActiveData
|
|
6
8
|
extend ActiveSupport::Concern
|
7
9
|
|
8
10
|
included do
|
9
|
-
class_attribute :_associations, :
|
10
|
-
self._associations =
|
11
|
+
class_attribute :_associations, instance_reader: false, instance_writer: false
|
12
|
+
self._associations = {}
|
13
|
+
|
14
|
+
{ embeds_many: EmbedsMany, embeds_one: EmbedsOne }.each do |(name, association_class)|
|
15
|
+
define_singleton_method name do |*args|
|
16
|
+
association = association_class.new *args
|
17
|
+
association.define_accessor self
|
18
|
+
self._associations = _associations.merge(association.name => association)
|
19
|
+
end
|
20
|
+
end
|
11
21
|
end
|
12
22
|
|
13
23
|
module ClassMethods
|
14
24
|
|
15
25
|
def reflect_on_association name
|
16
|
-
_associations[name]
|
26
|
+
_associations[name.to_s]
|
17
27
|
end
|
18
28
|
|
19
29
|
def associations
|
@@ -23,27 +33,14 @@ module ActiveData
|
|
23
33
|
def association_names
|
24
34
|
_associations.keys
|
25
35
|
end
|
36
|
+
end
|
26
37
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
define_collection_writer association
|
31
|
-
self._associations = _associations.merge!(association.name => association)
|
32
|
-
end
|
33
|
-
|
34
|
-
def define_collection_reader association
|
35
|
-
define_method association.name do
|
36
|
-
instance_variable_get("@#{association.name}") || association.klass.collection([])
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
def define_collection_writer association
|
41
|
-
define_method "#{association.name}=" do |value|
|
42
|
-
instance_variable_set "@#{association.name}", association.klass.collection(value)
|
43
|
-
end
|
38
|
+
def == other
|
39
|
+
super(other) && self.class.association_names.all? do |association|
|
40
|
+
send(association) == other.send(association)
|
44
41
|
end
|
45
|
-
|
46
42
|
end
|
43
|
+
|
47
44
|
end
|
48
45
|
end
|
49
46
|
end
|
@@ -5,15 +5,21 @@ module ActiveData
|
|
5
5
|
|
6
6
|
included do
|
7
7
|
class_attribute :_attributes, :instance_reader => false, :instance_writer => false
|
8
|
-
self._attributes =
|
9
|
-
|
10
|
-
extend generated_class_attributes_methods
|
11
|
-
include generated_instance_attributes_methods
|
8
|
+
self._attributes = {}
|
12
9
|
|
13
10
|
delegate :attribute_default, :to => 'self.class'
|
14
11
|
end
|
15
12
|
|
16
13
|
module ClassMethods
|
14
|
+
def attribute name, options = {}, &block
|
15
|
+
attribute = build_attribute(name, options, &block)
|
16
|
+
self._attributes = _attributes.merge(attribute.name => attribute)
|
17
|
+
|
18
|
+
attribute.generate_instance_methods generated_instance_attributes_methods
|
19
|
+
attribute.generate_class_methods generated_class_attributes_methods
|
20
|
+
attribute
|
21
|
+
end
|
22
|
+
|
17
23
|
def build_attribute name, options = {}, &block
|
18
24
|
klass = case options[:type].to_s
|
19
25
|
when 'Localized'
|
@@ -24,47 +30,44 @@ module ActiveData
|
|
24
30
|
klass.new name, options, &block
|
25
31
|
end
|
26
32
|
|
27
|
-
def attribute name, options = {}, &block
|
28
|
-
attribute = build_attribute(name, options, &block)
|
29
|
-
self._attributes = _attributes.merge(attribute.name => attribute)
|
30
|
-
|
31
|
-
attribute.generate_instance_methods generated_instance_attributes_methods
|
32
|
-
attribute.generate_singleton_methods generated_class_attributes_methods
|
33
|
-
attribute
|
34
|
-
end
|
35
|
-
|
36
33
|
def generated_class_attributes_methods
|
37
|
-
@generated_class_attributes_methods ||= Module.new
|
34
|
+
@generated_class_attributes_methods ||= Module.new.tap { |proxy| extend proxy }
|
38
35
|
end
|
39
36
|
|
40
37
|
def generated_instance_attributes_methods
|
41
|
-
@generated_instance_attributes_methods ||= Module.new
|
38
|
+
@generated_instance_attributes_methods ||= Module.new.tap { |proxy| include proxy }
|
42
39
|
end
|
43
40
|
|
44
41
|
def initialize_attributes
|
45
|
-
_attributes.
|
46
|
-
result[name] = nil
|
47
|
-
result
|
48
|
-
end
|
42
|
+
Hash[_attributes.map { |(name, _)| [name, nil] }]
|
49
43
|
end
|
50
44
|
end
|
51
45
|
|
52
46
|
def read_attribute name
|
53
|
-
|
54
|
-
|
55
|
-
|
47
|
+
name = name.to_sym
|
48
|
+
if attributes_cache.key? name
|
49
|
+
attributes_cache[name]
|
50
|
+
else
|
51
|
+
attribute = self.class._attributes[name]
|
52
|
+
value = attribute.type_cast @attributes[name]
|
53
|
+
use_default = attribute.default_blank? && value.blank? || value.nil?
|
54
|
+
|
55
|
+
attributes_cache[name] = use_default ? attribute.default_value(self) : value
|
56
|
+
end
|
56
57
|
end
|
57
58
|
alias_method :[], :read_attribute
|
58
59
|
|
59
60
|
def has_attribute? name
|
60
|
-
@attributes.key? name
|
61
|
+
@attributes.key? name.to_sym
|
61
62
|
end
|
62
63
|
|
63
64
|
def read_attribute_before_type_cast name
|
64
|
-
@attributes[name]
|
65
|
+
@attributes[name.to_sym]
|
65
66
|
end
|
66
67
|
|
67
68
|
def write_attribute name, value
|
69
|
+
name = name.to_sym
|
70
|
+
attributes_cache.delete name
|
68
71
|
@attributes[name] = value
|
69
72
|
end
|
70
73
|
alias_method :[]=, :write_attribute
|
@@ -87,9 +90,10 @@ module ActiveData
|
|
87
90
|
def attributes= attributes
|
88
91
|
assign_attributes(attributes)
|
89
92
|
end
|
93
|
+
alias_method :update_attributes, :attributes=
|
90
94
|
|
91
|
-
def
|
92
|
-
|
95
|
+
def write_attributes attributes
|
96
|
+
attributes.each { |(name, value)| send("#{name}=", value) }
|
93
97
|
end
|
94
98
|
|
95
99
|
def reverse_update_attributes attributes
|
@@ -98,18 +102,20 @@ module ActiveData
|
|
98
102
|
|
99
103
|
private
|
100
104
|
|
105
|
+
def attributes_cache
|
106
|
+
@attributes_cache ||= {}
|
107
|
+
end
|
108
|
+
|
101
109
|
def assign_attributes attributes
|
102
110
|
(attributes.presence || {}).each do |(name, value)|
|
103
|
-
send("#{name}=", value) if respond_to?("#{name}=")
|
111
|
+
send("#{name}=", value) if has_attribute?(name) || respond_to?("#{name}=")
|
104
112
|
end
|
105
|
-
self.attributes
|
106
113
|
end
|
107
114
|
|
108
115
|
def reverse_assign_attributes attributes
|
109
116
|
(attributes.presence || {}).each do |(name, value)|
|
110
117
|
send("#{name}=", value) if respond_to?("#{name}=") && respond_to?(name) && send(name).blank?
|
111
118
|
end
|
112
|
-
self.attributes
|
113
119
|
end
|
114
120
|
|
115
121
|
end
|
@@ -6,27 +6,24 @@ module ActiveData
|
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
|
8
8
|
included do
|
9
|
-
|
9
|
+
class_attribute :_collection_superclass
|
10
|
+
collectionize
|
10
11
|
end
|
11
12
|
|
12
13
|
module ClassMethods
|
13
14
|
|
14
|
-
def collectionize collection_superclass =
|
15
|
-
|
16
|
-
include ActiveData::Model::Collectionizable::Proxy
|
17
|
-
end
|
18
|
-
collection.collectible = self
|
19
|
-
|
20
|
-
remove_const :Collection if const_defined? :Collection
|
21
|
-
const_set :Collection, collection
|
15
|
+
def collectionize collection_superclass = Array
|
16
|
+
self._collection_superclass = collection_superclass
|
22
17
|
end
|
23
18
|
|
24
|
-
def
|
19
|
+
def respond_to_missing? method, include_private
|
25
20
|
super || collection_class.superclass.method_defined?(method)
|
26
21
|
end
|
27
22
|
|
28
23
|
def method_missing method, *args, &block
|
29
|
-
|
24
|
+
collection_class.superclass.method_defined?(method) ?
|
25
|
+
current_scope.send(method, *args, &block) :
|
26
|
+
super
|
30
27
|
end
|
31
28
|
|
32
29
|
def collection source = nil
|
@@ -34,7 +31,11 @@ module ActiveData
|
|
34
31
|
end
|
35
32
|
|
36
33
|
def collection_class
|
37
|
-
@collection_class ||=
|
34
|
+
@collection_class ||= begin
|
35
|
+
Class.new(_collection_superclass) do
|
36
|
+
include ActiveData::Model::Collectionizable::Proxy
|
37
|
+
end.tap { |klass| klass.collectible = self }
|
38
|
+
end
|
38
39
|
end
|
39
40
|
|
40
41
|
def current_scope= value
|
@@ -7,10 +7,10 @@ module ActiveData
|
|
7
7
|
module ClassMethods
|
8
8
|
def active_data_type_cast value
|
9
9
|
case value
|
10
|
-
when
|
11
|
-
value.split(',').map(&:strip)
|
12
|
-
when Array then
|
10
|
+
when ::Array then
|
13
11
|
value
|
12
|
+
when ::String then
|
13
|
+
value.split(',').map(&:strip)
|
14
14
|
else
|
15
15
|
nil
|
16
16
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module ActiveData
|
1
|
+
module ActiveData
|
2
2
|
module Model
|
3
3
|
module Extensions
|
4
4
|
module BigDecimal
|
@@ -6,7 +6,7 @@ module ActiveData
|
|
6
6
|
|
7
7
|
module ClassMethods
|
8
8
|
def active_data_type_cast value
|
9
|
-
::BigDecimal.new value.to_s if value
|
9
|
+
::BigDecimal.new Float(value).to_s rescue nil if value
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
@@ -6,14 +6,7 @@ module ActiveData
|
|
6
6
|
|
7
7
|
module ClassMethods
|
8
8
|
def active_data_type_cast value
|
9
|
-
|
10
|
-
when String then
|
11
|
-
Date.parse(value.to_s) rescue nil
|
12
|
-
when Date, DateTime, Time then
|
13
|
-
value.to_date
|
14
|
-
else
|
15
|
-
nil
|
16
|
-
end
|
9
|
+
value.to_date rescue nil
|
17
10
|
end
|
18
11
|
end
|
19
12
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ActiveData
|
2
|
+
module Model
|
3
|
+
module Extensions
|
4
|
+
module DateTime
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def active_data_type_cast value
|
9
|
+
value.to_datetime rescue nil
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
DateTime.send :include, ActiveData::Model::Extensions::DateTime
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ActiveData
|
2
|
+
module Model
|
3
|
+
module Extensions
|
4
|
+
module Object
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def active_data_type_cast value
|
9
|
+
value
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
Object.send :include, ActiveData::Model::Extensions::Object
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ActiveData
|
2
|
+
module Model
|
3
|
+
module Extensions
|
4
|
+
module Time
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
def active_data_type_cast value
|
9
|
+
value.to_time rescue nil
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
Time.send :include, ActiveData::Model::Extensions::Time
|
@@ -17,13 +17,13 @@ module ActiveData
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def read_localized_attribute name, locale = self.class.locale
|
20
|
-
translations = read_attribute(name)
|
21
|
-
translations[self.class.fallbacks(locale).detect { |fallback| translations[fallback.to_s] }]
|
20
|
+
translations = read_attribute(name.to_s)
|
21
|
+
translations[self.class.fallbacks(locale).detect { |fallback| translations[fallback.to_s] }.to_s]
|
22
22
|
end
|
23
23
|
alias_method :read_localized_attribute_before_type_cast, :read_localized_attribute
|
24
24
|
|
25
25
|
def write_localized_attribute name, value, locale = self.class.locale
|
26
|
-
translations = read_attribute(name)
|
26
|
+
translations = read_attribute(name.to_s)
|
27
27
|
write_attribute(name, translations.merge(locale.to_s => value))
|
28
28
|
end
|
29
29
|
end
|
@@ -43,10 +43,16 @@ module ActiveData
|
|
43
43
|
|
44
44
|
reflection = self.class.reflect_on_association association_name
|
45
45
|
|
46
|
-
send
|
47
|
-
|
48
|
-
|
46
|
+
send "#{association_name}=", attributes_collection
|
47
|
+
end
|
48
|
+
|
49
|
+
def assign_nested_attributes_for_one_to_one_association(association_name, attributes, assignment_opts = {})
|
50
|
+
unless attributes.is_a?(Hash)
|
51
|
+
raise ArgumentError, "Hash expected, got #{attributes.class.name} (#{attributes.inspect})"
|
52
|
+
end
|
53
|
+
|
54
|
+
send "#{association_name}=", attributes
|
49
55
|
end
|
50
56
|
end
|
51
57
|
end
|
52
|
-
end
|
58
|
+
end
|