smooth_operator 1.21.0 → 1.21.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- M2EyMTBiMWExYzQ4Mjc0ZDM3M2IyMGRkZmFjMTEzYmVjYzg5NDJkMw==
4
+ N2I1ZjBjNDAwNjFjNzE5ODJkNmE4ZTA0MGViZjYxMjgzOGNiNzM2ZQ==
5
5
  data.tar.gz: !binary |-
6
- YmZjYzA1YWM0ZjJmYzMwOWZjN2ZmMzVkMjRiNDFlYzc5MjVmYzNlNQ==
6
+ YzBmMWExNmJiMzJjNWMxMTFhNDFlYWQ4YjBmMGI4ZmNlNTUyZjJlOQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- Mzg4ZGRhNDA4NWJjNmEzNDkzMWNjYjZhZTM5YTFiMGRiMmUzZWNmOWFmMzg4
10
- NjFiMGVjMDJhZGRkNTExNzdhNTAzOTU4MjQxNmVmZTBiMzIxM2Q5Y2I5MzZh
11
- MTlhYTZiYWYxNWU1OTZjZmM0YjQ0ZjFlMTYxMjIxZjE5NWMzMmE=
9
+ YTYxZmRjNmVlNGViM2MyZjU0NjJiNDhkNWMyN2QyNmU0MmU1YmEzOWY4ZWRh
10
+ NDE2MDliOTAwZjNjMzRkZDliYmQ3MDc4NjAyMDZjMGRjMGFhZjQ4OWU2ZGYw
11
+ YjVlYzkwNjYxZjJiNTgzNDM5M2E4MzFkNzQ0Y2U3MGM2YTRhYTA=
12
12
  data.tar.gz: !binary |-
13
- ODljN2NlMTBlZDM1NWYwMzhlZmJjMDBkNDM3ZGEwOTYzZmNmZGFmNDQwMjUy
14
- OWFhNjNmODRlNmUxYmI3MzdlZWQzZGEzZjg1MzE3ZmZkZDY2NmI5YjZiMDNj
15
- OTdhNTA0OWNlMTk5NmM2OTNkZTlkZTlkODZhNDZiODhhNmVhZjc=
13
+ N2I4MjM1YjI1MzE5YjhjOGJjNDZkMzU0MTBhMzE5OGFhMTA3MDIwOWNlYzE2
14
+ OWI2N2I0MjdiYTg1NDhlZDNkMmRiNDI5YmEyOWNjNzY2YWVhZGZlMzcyMDUw
15
+ ZWMzZmNjYjZkNDAzOTdmOWJjNTAxMTU3MjA2MzQ2M2VkOGRkNWE=
data/README.md CHANGED
@@ -1,11 +1,19 @@
1
- # SmoothOperator
1
+ # SmoothOperator [![Code Climate](https://codeclimate.com/repos/536a7b9f6956801228014b02/badges/13f79897976274a9de33/gpa.png)](https://codeclimate.com/repos/536a7b9f6956801228014b02/feed)
2
2
 
3
3
  Ruby gem, that mimics the ActiveRecord behaviour but through external API's.
4
4
  It's a lightweight and flexible alternative to ActiveResource, that responds to a REST API like you expect it too.
5
5
 
6
- Depends only on Faraday gem, no need for ActiveSupport or any other Active* gem.
6
+ Be sure to check out this micro-services example: https://github.com/goncalvesjoao/micro-services-example
7
7
 
8
- Although if I18n is present it will respond to .human_attribute_name method and if ActiveModel is present it will make use of 'ActiveModel::Name' to improve .model_name method.
8
+ Where a Rails4 app lists/creates/edits and destroys blog posts from a Padrino (aka Sinatra) app, using SmoothOperator::Rails instead of ActiveRecord::Base classes.
9
+
10
+ This micro-services example will also feature other cool stuff like:
11
+ - parallel requests;
12
+ - using HTTP PATCH verb for saving instead of PUT;
13
+ - form errors with simple_form gem;
14
+ - nested objects using cocoon gem;
15
+ - endless-pagination with kaminari gem
16
+ - and others...
9
17
 
10
18
  ---
11
19
 
@@ -13,7 +13,7 @@ module SmoothOperator
13
13
  attributes.delete(resources_name)
14
14
 
15
15
  @meta_data = attributes
16
-
16
+
17
17
  define_metada_methods
18
18
 
19
19
  super(@internal_array)
@@ -1,7 +1,7 @@
1
- require "smooth_operator/relation/reflection"
1
+ require "smooth_operator/associations/reflection"
2
2
 
3
3
  module SmoothOperator
4
- module Relation
4
+ module Associations
5
5
  class AssociationReflection < Reflection
6
6
 
7
7
  attr_reader :related_reflection, :macro
@@ -1,6 +1,6 @@
1
1
  module SmoothOperator
2
- module Relation
3
- class ArrayRelation < SimpleDelegator
2
+ module Associations
3
+ class HasManyRelation < SimpleDelegator
4
4
 
5
5
  attr_reader :object, :association
6
6
 
@@ -1,5 +1,5 @@
1
1
  module SmoothOperator
2
- module Relation
2
+ module Associations
3
3
  class Reflection
4
4
 
5
5
  attr_reader :name, :klass, :options
@@ -0,0 +1,100 @@
1
+ require "smooth_operator/associations/has_many_relation"
2
+ require "smooth_operator/associations/association_reflection"
3
+
4
+ module SmoothOperator
5
+ module Associations
6
+
7
+ def has_many(nested_object_name, options = {})
8
+ accepts_nested_objects(nested_object_name, :has_many, options)
9
+ end
10
+
11
+ def has_one(nested_object_name, options = {})
12
+ accepts_nested_objects(nested_object_name, :has_one, options)
13
+ end
14
+
15
+ def belongs_to(nested_object_name, options = {})
16
+ accepts_nested_objects(nested_object_name, :belongs_to, options)
17
+ end
18
+
19
+ def reflections
20
+ Helpers.get_instance_variable(self, :reflections, {})
21
+ end
22
+
23
+ def reflect_on_association(association)
24
+ reflections[association]
25
+ end
26
+
27
+ def reflect_on_all_associations(macro = nil)
28
+ macro ? reflections.values.select { |reflection| reflection.macro == macro } : reflections.values
29
+ end
30
+
31
+ protected ###################### PROTECTED ###################
32
+
33
+ def accepts_nested_objects(association, macro, options = {})
34
+ options = parse_options(options, { macro: macro })
35
+
36
+ reflection = AssociationReflection.new(association, Reflection.new(name, {}), options)
37
+
38
+ schema(association => reflection.klass)
39
+
40
+ reflections.merge!(association => reflection)
41
+
42
+ if reflection.has_many?
43
+ define_has_many_association_method(reflection, association)
44
+ else
45
+ define_single_association_method(reflection, association)
46
+ end
47
+
48
+ self.send(:attr_reader, "#{association}_attributes".to_sym)
49
+
50
+ define_attributes_setter_methods(reflection, association)
51
+ end
52
+
53
+ private ####################### PRIVATE ######################
54
+
55
+ def define_has_many_association_method(reflection, association)
56
+ define_method(association) do
57
+ has_many_relation = instance_variable_get("@#{association}")
58
+
59
+ if has_many_relation.nil?
60
+ has_many_relation = HasManyRelation.new(self, association)
61
+
62
+ instance_variable_set("@#{association}", has_many_relation)
63
+ end
64
+
65
+ has_many_relation.send(:refresh)
66
+
67
+ has_many_relation
68
+ end
69
+ end
70
+
71
+ def define_single_association_method(reflection, association)
72
+ define_method(association) { internal_data_get(association.to_s) }
73
+
74
+ define_method("build_#{association}") do |attributes = {}|
75
+ new_instance = reflection.klass.new(attributes)
76
+
77
+ internal_data_push(association, new_instance)
78
+
79
+ new_instance
80
+ end
81
+ end
82
+
83
+ def define_attributes_setter_methods(reflection, association)
84
+ define_method("#{association}_attributes=") do |attributes|
85
+ instance_variable_set("@#{association}_attributes", attributes)
86
+
87
+ attributes = attributes.values if reflection.has_many?
88
+
89
+ internal_data_push(association.to_s, attributes)
90
+ end
91
+ end
92
+
93
+ def parse_options(options, default_options)
94
+ options = options.is_a?(Hash) ? options.merge(default_options) : default_options
95
+
96
+ Helpers.symbolyze_keys(options)
97
+ end
98
+
99
+ end
100
+ end
@@ -23,7 +23,7 @@ module SmoothOperator
23
23
  @_meta_data = _attributes
24
24
  end
25
25
 
26
- @_internal_errors = attributes.delete(self.class.errors_key)
26
+ induce_errors(attributes.delete(self.class.errors_key))
27
27
 
28
28
  options.each { |key, value| @_options[key] = value } if options.is_a? Hash
29
29
 
@@ -34,10 +34,6 @@ module SmoothOperator
34
34
  end
35
35
  end
36
36
 
37
- def _parent_object
38
- _options[:parent_object]
39
- end
40
-
41
37
  protected ################# PROTECTED METHODS DOWN BELOW ###################
42
38
 
43
39
  def before_initialize(attributes, options); end
@@ -0,0 +1,17 @@
1
+ module SmoothOperator
2
+ module HttpMethods
3
+
4
+ HTTP_VERBS = %w[get post put patch delete]
5
+
6
+ HTTP_VERBS.each do |method|
7
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
8
+ def #{method}(relative_path = '', params = {}, options = {})
9
+ make_the_call(:#{method}, relative_path, params, options) do |remote_call|
10
+ block_given? ? yield(remote_call) : remote_call
11
+ end
12
+ end
13
+ RUBY
14
+ end
15
+
16
+ end
17
+ end
@@ -12,10 +12,12 @@ module SmoothOperator
12
12
 
13
13
  relative_path = resource_path(relative_path)
14
14
 
15
- if !_parent_object.nil? && options[:ignore_parent] != true
16
- id = Helpers.primary_key(_parent_object)
15
+ parent_object = _options[:parent_object]
17
16
 
18
- options[:resources_name] ||= "#{_parent_object.class.resources_name}/#{id}/#{self.class.resources_name}"
17
+ if !parent_object.nil? && options[:ignore_parent] != true
18
+ id = Helpers.primary_key(parent_object)
19
+
20
+ options[:resources_name] ||= "#{parent_object.class.resources_name}/#{id}/#{self.class.resources_name}"
19
21
  end
20
22
 
21
23
  self.class.make_the_call(http_verb, relative_path, data, options) do |remote_call|
@@ -23,8 +25,6 @@ module SmoothOperator
23
25
  end
24
26
  end
25
27
 
26
- protected ######################## PROTECTED ###################
27
-
28
28
  def resource_path(relative_path)
29
29
  if Helpers.absolute_path?(relative_path)
30
30
  Helpers.remove_initial_slash(relative_path)
@@ -41,24 +41,6 @@ module SmoothOperator
41
41
  base.extend(ClassMethods)
42
42
  end
43
43
 
44
- ########################### MODULES BELLOW ###############################
45
-
46
- module HttpMethods
47
-
48
- HTTP_VERBS = %w[get post put patch delete]
49
-
50
- HTTP_VERBS.each do |method|
51
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
52
- def #{method}(relative_path = '', params = {}, options = {})
53
- make_the_call(:#{method}, relative_path, params, options) do |remote_call|
54
- block_given? ? yield(remote_call) : remote_call
55
- end
56
- end
57
- RUBY
58
- end
59
-
60
- end
61
-
62
44
  module ClassMethods
63
45
 
64
46
  OPTIONS = [:endpoint, :endpoint_user, :endpoint_pass, :timeout]
@@ -76,15 +58,15 @@ module SmoothOperator
76
58
  attr_writer :headers
77
59
 
78
60
  def make_the_call(http_verb, relative_path = '', data = {}, options = {})
79
- operator_args = operator_method_args(http_verb, relative_path, data, options)
61
+ options = HelperMethods.populate_options(self, options)
80
62
 
81
- if Helpers.present?(operator_args[4][:hydra])
82
- operator_call = Operators::Typhoeus
83
- else
84
- operator_call = Operators::Faraday
85
- end
63
+ resource_path = resource_path(relative_path, options)
64
+
65
+ params, data = *HelperMethods.strip_params(self, http_verb, data)
86
66
 
87
- operator_call.make_the_call(*operator_args) do |remote_call|
67
+ operator = HelperMethods.get_me_an_operator(options)
68
+
69
+ operator.make_the_call(http_verb, resource_path, params, data, options) do |remote_call|
88
70
  block_given? ? yield(remote_call) : remote_call
89
71
  end
90
72
  end
@@ -93,45 +75,52 @@ module SmoothOperator
93
75
  params
94
76
  end
95
77
 
96
- protected #################### PROTECTED ##################
97
-
98
- def operator_method_args(http_verb, relative_path, data, options)
99
- options = populate_options(options)
78
+ def resource_path(relative_path, options)
79
+ resources_name = options[:resources_name] || self.resources_name
100
80
 
101
- [http_verb, resource_path(relative_path, options), *strip_params(http_verb, data), options]
81
+ if Helpers.present?(resources_name)
82
+ Helpers.present?(relative_path) ? "#{resources_name}/#{relative_path}" : resources_name
83
+ else
84
+ relative_path.to_s
85
+ end
102
86
  end
103
87
 
104
- private #################### PRIVATE ##################
105
-
106
- def populate_options(options)
107
- options ||= {}
88
+ end
108
89
 
109
- OPTIONS.each { |option| options[option] ||= send(option) }
90
+ module HelperMethods
110
91
 
111
- options[:headers] = headers.merge(options[:headers] || {})
92
+ extend self
112
93
 
113
- options
94
+ def get_me_an_operator(options)
95
+ if options[:parallel_connection].nil?
96
+ Operators::Faraday
97
+ else
98
+ Operators::Typhoeus
99
+ end
114
100
  end
115
101
 
116
- def resource_path(relative_path, options)
117
- _resources_name = options[:resources_name] || self.resources_name
102
+ def populate_options(object, options)
103
+ options ||= {}
118
104
 
119
- if Helpers.present?(_resources_name)
120
- Helpers.present?(relative_path) ? "#{_resources_name}/#{relative_path}" : _resources_name
121
- else
122
- relative_path.to_s
105
+ ClassMethods::OPTIONS.each do |option|
106
+ options[option] ||= object.send(option)
123
107
  end
108
+
109
+ options[:headers] = object.headers.merge(options[:headers] || {})
110
+
111
+ options
124
112
  end
125
113
 
126
- def strip_params(http_verb, data)
114
+ def strip_params(object, http_verb, data)
127
115
  data ||= {}
128
116
 
129
117
  if [:get, :head, :delete].include?(http_verb)
130
- [query_string(data), nil]
118
+ [object.query_string(data), nil]
131
119
  else
132
- [query_string({}), data]
120
+ [object.query_string({}), data]
133
121
  end
134
122
  end
123
+
135
124
  end
136
125
 
137
126
  end
@@ -43,7 +43,7 @@ module SmoothOperator
43
43
  raise 'UnknownPath'
44
44
  end
45
45
 
46
- _persistence_call(:reload, relative_path, data, options) do |remote_call|
46
+ make_a_persistence_call(:reload, relative_path, data, options) do |remote_call|
47
47
  block_given? ? yield(remote_call) : remote_call.status
48
48
  end
49
49
  end
@@ -67,7 +67,7 @@ module SmoothOperator
67
67
  def destroy(relative_path = nil, data = {}, options = {})
68
68
  return false unless persisted?
69
69
 
70
- _persistence_call(:destroy, relative_path, data, options) do |remote_call|
70
+ make_a_persistence_call(:destroy, relative_path, data, options) do |remote_call|
71
71
  @destroyed = true if remote_call.status
72
72
 
73
73
  block_given? ? yield(remote_call) : remote_call.status
@@ -77,7 +77,7 @@ module SmoothOperator
77
77
  protected ######################### PROTECTED ##################
78
78
 
79
79
  def create(relative_path, data, options)
80
- _persistence_call(:create, relative_path, data, options) do |remote_call|
80
+ make_a_persistence_call(:create, relative_path, data, options) do |remote_call|
81
81
  @new_record = false if remote_call.status
82
82
 
83
83
  block_given? ? yield(remote_call) : remote_call
@@ -85,7 +85,7 @@ module SmoothOperator
85
85
  end
86
86
 
87
87
  def update(relative_path, data, options)
88
- _persistence_call(:update, relative_path, data, options) do |remote_call|
88
+ make_a_persistence_call(:update, relative_path, data, options) do |remote_call|
89
89
  block_given? ? yield(remote_call) : remote_call
90
90
  end
91
91
  end
@@ -102,7 +102,7 @@ module SmoothOperator
102
102
 
103
103
  private ##################### PRIVATE ##################
104
104
 
105
- def _persistence_call(method, relative_path, data, options)
105
+ def make_a_persistence_call(method, relative_path, data, options)
106
106
  options ||= {}
107
107
 
108
108
  http_verb = options[:http_verb] || self.class.methods_vs_http_verbs[method]
@@ -6,8 +6,7 @@ module SmoothOperator
6
6
  end
7
7
 
8
8
  def internal_structure
9
- Helpers.get_instance_variable(self, :internal_structure,
10
- { primary_key => nil })
9
+ Helpers.get_instance_variable(self, :internal_structure, {})
11
10
  end
12
11
 
13
12
  def known_attribute?(attribute)
@@ -2,15 +2,23 @@ module SmoothOperator
2
2
  module Validations
3
3
 
4
4
  def valid?(context = nil)
5
- Helpers.blank?(_internal_errors)
5
+ Helpers.blank?(induced_errors)
6
6
  end
7
7
 
8
8
  def invalid?
9
9
  !valid?
10
10
  end
11
11
 
12
- def _internal_errors
13
- @_internal_errors ||= {}
12
+ def induced_errors
13
+ @induced_errors ||= {}
14
+ end
15
+
16
+ def clear_induced_errors
17
+ @induced_errors = {}
18
+ end
19
+
20
+ def induce_errors(value)
21
+ @induced_errors = value
14
22
  end
15
23
 
16
24
  def self.included(base)
@@ -1,3 +1,3 @@
1
1
  module SmoothOperator
2
- VERSION = "1.21.0"
2
+ VERSION = "1.21.1"
3
3
  end
@@ -5,22 +5,23 @@ require "smooth_operator/operator"
5
5
  require "smooth_operator/persistence"
6
6
  require "smooth_operator/translation"
7
7
  require "smooth_operator/open_struct"
8
+ require "smooth_operator/http_methods"
9
+ require "smooth_operator/associations"
8
10
  require "smooth_operator/finder_methods"
9
- require "smooth_operator/relation/associations"
10
11
 
11
12
  module SmoothOperator
12
13
  class Base < OpenStruct
13
14
 
14
15
  extend Schema
16
+ extend HttpMethods
17
+ extend Associations
15
18
  extend FinderMethods
16
- extend Operator::HttpMethods
17
- extend Relation::Associations
18
19
  extend Translation if defined? I18n
19
20
 
20
21
  include Operator
22
+ include HttpMethods
21
23
  include Persistence
22
24
  include FinderMethods
23
- include Operator::HttpMethods
24
25
 
25
26
  self.strict_behaviour = true
26
27
 
@@ -37,6 +38,8 @@ module SmoothOperator
37
38
  include ActiveModel::Validations::Callbacks
38
39
  include ActiveModel::Conversion
39
40
 
41
+ validate :validate_induced_errors, :validate_nested_objects
42
+
40
43
  def column_for_attribute(attribute_name)
41
44
  type = self.class.attribute_type(attribute_name)
42
45
 
@@ -44,12 +47,11 @@ module SmoothOperator
44
47
  end
45
48
 
46
49
  def save(relative_path = nil, data = {}, options = {})
47
- # clear_server_errors
48
50
  return false unless before_save
49
51
 
50
- save_result = valid? ? super : false
52
+ clear_induced_errors
51
53
 
52
- # import_server_errors
54
+ save_result = valid? ? super : false
53
55
 
54
56
  after_save if valid? && save_result
55
57
 
@@ -62,6 +64,22 @@ module SmoothOperator
62
64
 
63
65
  def after_save; end
64
66
 
67
+ protected ################# PROTECTED ###################
68
+
69
+ def validate_induced_errors
70
+ induced_errors.each do |key, value|
71
+ [*value].each do |_value|
72
+ self.errors.add(key, _value) unless self.errors.added?(key, _value)
73
+ end
74
+ end
75
+
76
+ Helpers.blank?(induced_errors)
77
+ end
78
+
79
+ def validate_nested_objects
80
+ # nested_objects.map { |reflection, nested_object| nested_object.valid? }.all?
81
+ end
82
+
65
83
  end
66
84
  end
67
85
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smooth_operator
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.21.0
4
+ version: 1.21.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - João Gonçalves
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-31 00:00:00.000000000 Z
11
+ date: 2014-06-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -82,20 +82,21 @@ files:
82
82
  - console.rb
83
83
  - lib/smooth_operator.rb
84
84
  - lib/smooth_operator/array_with_meta_data.rb
85
+ - lib/smooth_operator/associations.rb
86
+ - lib/smooth_operator/associations/association_reflection.rb
87
+ - lib/smooth_operator/associations/has_many_relation.rb
88
+ - lib/smooth_operator/associations/reflection.rb
85
89
  - lib/smooth_operator/attribute_assignment.rb
86
90
  - lib/smooth_operator/delegation.rb
87
91
  - lib/smooth_operator/finder_methods.rb
88
92
  - lib/smooth_operator/helpers.rb
93
+ - lib/smooth_operator/http_methods.rb
89
94
  - lib/smooth_operator/internal_data.rb
90
95
  - lib/smooth_operator/open_struct.rb
91
96
  - lib/smooth_operator/operator.rb
92
97
  - lib/smooth_operator/operators/faraday.rb
93
98
  - lib/smooth_operator/operators/typhoeus.rb
94
99
  - lib/smooth_operator/persistence.rb
95
- - lib/smooth_operator/relation/array_relation.rb
96
- - lib/smooth_operator/relation/association_reflection.rb
97
- - lib/smooth_operator/relation/associations.rb
98
- - lib/smooth_operator/relation/reflection.rb
99
100
  - lib/smooth_operator/remote_call/base.rb
100
101
  - lib/smooth_operator/remote_call/errors/connection_failed.rb
101
102
  - lib/smooth_operator/remote_call/errors/timeout.rb
@@ -1,102 +0,0 @@
1
- require "smooth_operator/relation/array_relation"
2
- require "smooth_operator/relation/association_reflection"
3
-
4
- module SmoothOperator
5
- module Relation
6
- module Associations
7
-
8
- def has_many(nested_object_name, options = {})
9
- accepts_nested_objects(nested_object_name, :has_many, options)
10
- end
11
-
12
- def has_one(nested_object_name, options = {})
13
- accepts_nested_objects(nested_object_name, :has_one, options)
14
- end
15
-
16
- def belongs_to(nested_object_name, options = {})
17
- accepts_nested_objects(nested_object_name, :belongs_to, options)
18
- end
19
-
20
- def reflections
21
- Helpers.get_instance_variable(self, :reflections, {})
22
- end
23
-
24
- def reflect_on_association(association)
25
- reflections[association]
26
- end
27
-
28
- def reflect_on_all_associations(macro = nil)
29
- macro ? reflections.values.select { |reflection| reflection.macro == macro } : reflections.values
30
- end
31
-
32
- protected ###################### PROTECTED ###################
33
-
34
- def accepts_nested_objects(association, macro, options = {})
35
- options = parse_options(options, { macro: macro })
36
-
37
- reflection = AssociationReflection.new(association, Reflection.new(name, {}), options)
38
-
39
- schema(association => reflection.klass)
40
-
41
- reflections.merge!(association => reflection)
42
-
43
- if reflection.has_many?
44
- define_has_many_association_method(reflection, association)
45
- else
46
- define_single_association_method(reflection, association)
47
- end
48
-
49
- self.send(:attr_reader, "#{association}_attributes".to_sym)
50
-
51
- define_attributes_setter_methods(reflection, association)
52
- end
53
-
54
- private ####################### PRIVATE ######################
55
-
56
- def define_has_many_association_method(reflection, association)
57
- define_method(association) do
58
- array_relation = instance_variable_get("@#{association}")
59
-
60
- if array_relation.nil?
61
- array_relation = ArrayRelation.new(self, association)
62
-
63
- instance_variable_set("@#{association}", array_relation)
64
- end
65
-
66
- array_relation.send(:refresh)
67
-
68
- array_relation
69
- end
70
- end
71
-
72
- def define_single_association_method(reflection, association)
73
- define_method(association) { internal_data_get(association.to_s) }
74
-
75
- define_method("build_#{association}") do |attributes = {}|
76
- new_instance = reflection.klass.new(attributes)
77
-
78
- internal_data_push(association, new_instance)
79
-
80
- new_instance
81
- end
82
- end
83
-
84
- def define_attributes_setter_methods(reflection, association)
85
- define_method("#{association}_attributes=") do |attributes|
86
- instance_variable_set("@#{association}_attributes", attributes)
87
-
88
- attributes = attributes.values if reflection.has_many?
89
-
90
- internal_data_push(association.to_s, attributes)
91
- end
92
- end
93
-
94
- def parse_options(options, default_options)
95
- options = options.is_a?(Hash) ? options.merge(default_options) : default_options
96
-
97
- Helpers.symbolyze_keys(options)
98
- end
99
-
100
- end
101
- end
102
- end