active_form_objects 0.1.2 → 1.0.0.beta

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: daff81f1e757efcd09b602052b01108e5975ec4afdbc23eb990d9fd4fad28067
4
- data.tar.gz: bd751ee1875ac9ff54e70d107106cbc041e499dedd9bb8b44147c0f902ea44eb
3
+ metadata.gz: '03871811ee607637a50a7c85d85985dea846a563709f4d1b803aa681589e5517'
4
+ data.tar.gz: d6fb754563a486d09e99cb09dc183dc276d83f0d1ab9b8a11c83003a8920340e
5
5
  SHA512:
6
- metadata.gz: 23909b529fe45a1de257f237698b6be281d1ef4d8ec8d7f09a588783ced45552e4373ca185e6787a23f3be2552a3a8c3b08477b14daef69dc8082ebd1e026a60
7
- data.tar.gz: 3ed88b54b54be83db842ebb37565eecfe194bc12c970b01b26871ef0d95c0364705ea6b01e376ea6d584fb6877025c34ad6143e23902dc3cb6fb8c9c63ae80e7
6
+ metadata.gz: f041ee7728861ab7112f9202284bb1d133c877fe42def63e9ba437efb2ebc87efb8ffab77f5a7d519001eba7639c51b03b87371e5c35d5586bde821dc7a18ce4
7
+ data.tar.gz: 362e0149393a0fd88f129e4169e16c3f037ec506610de8469fe6d33a5478f540c7fda66da8aafebe8be0981f17a200c58a011c94f0d695925ec1a5ff565bf194
@@ -1,97 +1,36 @@
1
- require 'active_support'
2
1
  require 'active_model'
3
- require 'active_support/core_ext/object/instance_variables'
4
- require 'active_support/core_ext/hash/indifferent_access'
5
- require_relative 'concerns/relations'
6
- require_relative 'concerns/savings'
2
+
3
+ require_relative 'dsl/relations'
4
+ require_relative 'dsl/attributes'
5
+ require_relative 'dsl/delegates'
6
+ require_relative 'dsl/savings'
7
+ require_relative 'dsl/resource'
8
+ require_relative 'dsl/polymorphs'
9
+
10
+ require_relative 'handlers/initializer'
11
+ require_relative 'handlers/relations'
12
+ require_relative 'handlers/resource'
13
+ require_relative 'handlers/attributes'
7
14
 
8
15
  module ActiveFormObjects
9
16
  class Base
10
17
  include ActiveModel::Model
11
- include Relations
12
- include Savings
13
-
14
- @@authorized_params = {}
15
- @@overrided_params = {}
16
- @@default_params = {}
17
- @@preparers = {}
18
- @@resource = {}
19
-
20
- attr_reader :resource
21
-
22
- def self.resource(resource = nil, &block)
23
- bloc_to_call = block || proc { resource }
24
- @@resource[name] = bloc_to_call
25
- end
26
-
27
- def self.prepare(*params)
28
- method_to_call = params.last[:with]
29
- @@preparers[name] = (@@preparers[name] || []) + [{
30
- key: params.first,
31
- method_to_call: method_to_call
32
- }]
33
- end
34
-
35
- def self.attributes(*params)
36
- @@authorized_params[name] = (@@authorized_params[name] || []) + params
37
- send(:attr_accessor, *params)
38
- end
39
-
40
- def self.delegate(*params)
41
- delegator = params.last
42
- params.pop
43
- send(:attributes, *params)
44
- define_method("#{delegator[:to]}_params") do
45
- attrs_only(params)
46
- end
47
- end
48
18
 
49
- def self.set_default(params)
50
- [params[:to]].flatten.each do |param|
51
- @@default_params[name] ||= {}
52
- @@default_params[name][param] = params[:value]
53
- end
54
- send(:attributes, *params[:to])
55
- end
56
-
57
- def self.ensure_value(param, value)
58
- @@overrided_params[name] ||= {}
59
- @@overrided_params[name][param] = value
60
-
61
- send(:attributes, param)
62
- end
19
+ include Dsl::Resource
20
+ include Dsl::Attributes
21
+ include Dsl::Relations
22
+ include Dsl::Polymorphs
23
+ include Dsl::Delegates
24
+ include Dsl::Savings
63
25
 
64
26
  def initialize(params, resource = nil)
65
- @resource = resource || @@resource[self.class.name].try(:call, params).try(:new)
66
- set_associated_forms
67
- params = affect_relation_values(params)
68
- resource_params(params || {})
69
-
70
- params_with_resource_attrs = @resource.respond_to?(:attributes) ? @resource.attributes.symbolize_keys.slice(*@authorized_params).merge(@params) : @params
71
- params_with_preprared_value = affect_prepared_values(params_with_resource_attrs)
72
- super(params_with_preprared_value)
73
- end
74
-
75
- def affect_prepared_values(params)
76
- (@@preparers[self.class.name] || []).each do |preparer|
77
- params[preparer[:key]] = params[preparer[:key]].try(preparer[:method_to_call])
78
- end
79
- params
80
- end
81
-
82
- def resource_params(params)
83
- @default_params = @@default_params[self.class.name] || {}
84
- @overrided_params = @@overrided_params[self.class.name] || {}
85
- @authorized_params = @@authorized_params[self.class.name] || {}
86
- @params = @default_params.merge(params.to_h.symbolize_keys).merge(@overrided_params).slice(*@authorized_params)
87
- end
88
-
89
- def attrs_only(params)
90
- attributes.slice(*params)
91
- end
27
+ @params = params
28
+ @resource = resource
92
29
 
93
- def attributes
94
- instance_values.with_indifferent_access.symbolize_keys
30
+ Handlers::Initializer.handle(self)
31
+ Handlers::Resource.handle(self)
32
+ Handlers::Attributes.handle(self)
33
+ super(@params)
95
34
  end
96
35
  end
97
36
  end
@@ -0,0 +1,44 @@
1
+ require 'active_support'
2
+
3
+ module Dsl
4
+ module Attributes
5
+ extend ActiveSupport::Concern
6
+
7
+ @@attributes = {}
8
+ @@overrided_params = {}
9
+ @@default_params = {}
10
+ @@preparers = {}
11
+
12
+ included do
13
+ attr_accessor :params
14
+
15
+ def self.attributes(*params)
16
+ @@attributes[name] = (@@attributes[name] || []) + params
17
+ attr_accessor(*params)
18
+ end
19
+
20
+ def self.set_default(params)
21
+ [params[:to]].flatten.each do |param|
22
+ @@default_params[name] ||= {}
23
+ @@default_params[name][param] = params[:value]
24
+ end
25
+ send(:attributes, *params[:to])
26
+ end
27
+
28
+ def self.ensure_value(param, value)
29
+ @@overrided_params[name] ||= {}
30
+ @@overrided_params[name][param] = value
31
+
32
+ send(:attributes, param)
33
+ end
34
+
35
+ def self.prepare(*params)
36
+ method_to_call = params.last[:with]
37
+ @@preparers[name] = (@@preparers[name] || []) + [{
38
+ key: params.first,
39
+ method_to_call: method_to_call
40
+ }]
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,18 @@
1
+ require 'active_support'
2
+
3
+ module Dsl
4
+ module Delegates
5
+ extend ActiveSupport::Concern
6
+
7
+ @@delegators = {}
8
+
9
+ included do
10
+ def self.delegate(*params)
11
+ delegator = params.last[:to].merge(attributes: params)
12
+ params.pop
13
+
14
+ @@delegators[name] = (@@delegators[name] || []) << delegator
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,35 @@
1
+ require 'active_support'
2
+ require 'active_model'
3
+
4
+ module Dsl
5
+ module Polymorphs
6
+ extend ActiveSupport::Concern
7
+
8
+ @@polymorphic_keys = {}
9
+
10
+ class_methods do
11
+ # Allows to declare a polymorphic relationship
12
+ #
13
+ # Params:
14
+ # +key+:: the corresponding key in the params hash
15
+ # +possible_types+:: A hash that follows the below format
16
+ #
17
+ # polymorph(:content, :program_id, {
18
+ # foo: Bar
19
+ # })
20
+ #
21
+ # Int the above example the possible_types hash :
22
+ # scannable => key
23
+ # Scannable => model class
24
+ #
25
+ def polymorph(key, possible_types)
26
+ @@polymorphic_keys[name] ||= []
27
+ @@polymorphic_keys[name] << {
28
+ key: key,
29
+ types: possible_types
30
+ }
31
+ send(:attributes, key)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,39 @@
1
+ require 'active_support'
2
+ require 'active_model'
3
+
4
+ module Dsl
5
+ module Relations
6
+ extend ActiveSupport::Concern
7
+
8
+ @@relation_keys = {}
9
+
10
+ class RelationValidator < ActiveModel::EachValidator
11
+ def validate_each(record, attribute, _)
12
+ record.errors.add(attribute, "#{attribute} or #{attribute}_id is required") unless record.try(attribute).present? || record.try("#{attribute}_id".to_sym).present?
13
+ end
14
+ end
15
+
16
+ class_methods do
17
+ # Allows to receive a relation as an input params.
18
+ # Relation can then be received either as :
19
+ # - relation_id => The key to the corresponding relation
20
+ # - relation => An instance of the object
21
+ #
22
+ # Params:
23
+ # +params+:: the list of relations to declare
24
+ #
25
+ # Example :
26
+ # relations(:entity, :user)
27
+ #
28
+ def relations(*params)
29
+ validates(*params, relation: true)
30
+
31
+ params.each do |param|
32
+ relation_key = "#{param}_id".to_sym
33
+ send(:attributes, param, relation_key)
34
+ @@relation_keys[name] = (@@relation_keys[name] || []) + [param]
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,18 @@
1
+ require 'active_support'
2
+
3
+ module Dsl
4
+ module Resource
5
+ extend ActiveSupport::Concern
6
+
7
+ @@resource = {}
8
+
9
+ included do
10
+ attr_reader :resource
11
+
12
+ def self.resource(resource = nil, &block)
13
+ bloc_to_call = block || proc { resource }
14
+ @@resource[name] = bloc_to_call
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,27 @@
1
+ require 'active_support'
2
+ require 'active_record'
3
+ require_relative '../handlers/savings'
4
+
5
+ module Dsl
6
+ module Savings
7
+ extend ActiveSupport::Concern
8
+
9
+ class_methods do
10
+ def save(&block)
11
+ define_method(:save!) do
12
+ Handlers::Savings.new(self).save!(&block)
13
+ end
14
+ end
15
+ end
16
+
17
+ def save!
18
+ Handlers::Savings.new(self).save!
19
+ end
20
+
21
+ def save
22
+ save!
23
+ rescue
24
+ false
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,52 @@
1
+ require 'active_support/core_ext/hash/reverse_merge'
2
+ require_relative 'base'
3
+ require_relative 'relations'
4
+ require_relative 'delegates'
5
+
6
+ module Handlers
7
+ class Attributes < Base
8
+ def handle
9
+ start_with_default_params!
10
+ affect_prepared_values!
11
+ merge_with_resource_attributes!
12
+ affect_relation_values!
13
+ merge_overrided_params!
14
+ slice_unauthorized_attributes!
15
+ end
16
+
17
+ # DSL method : set_default
18
+ def start_with_default_params!
19
+ default_params = upper(:@@default_params) || {}
20
+ @params.reverse_merge!(default_params)
21
+ end
22
+
23
+ # DSL method : prepare
24
+ def affect_prepared_values!
25
+ (upper(:@@preparers) || []).each do |preparer|
26
+ @params[preparer[:key]] = @params[preparer[:key]].try(preparer[:method_to_call])
27
+ end
28
+ end
29
+
30
+ def merge_with_resource_attributes!
31
+ return unless @resource.respond_to?(:attributes)
32
+ @params.reverse_merge!(@resource.attributes.symbolize_keys)
33
+ end
34
+
35
+ # DSL method : ensure_value
36
+ def merge_overrided_params!
37
+ overrided_params = upper(:@@overrided_params) || {}
38
+ @params.merge!(overrided_params)
39
+ end
40
+
41
+ # DSL method : relation
42
+ def affect_relation_values!
43
+ Relations.new(@klass).affect_relation_values!
44
+ end
45
+
46
+ # DSL method : attributes
47
+ def slice_unauthorized_attributes!
48
+ authorized_attributes = upper(:@@attributes) || {}
49
+ @params.slice!(*authorized_attributes)
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,18 @@
1
+ module Handlers
2
+ class Base
3
+ def initialize(klass)
4
+ @klass = klass
5
+ @raw_params = @klass.instance_variable_get(:@raw_params)
6
+ @params = @klass.instance_variable_get(:@params)
7
+ @resource = @klass.instance_variable_get(:@resource)
8
+ end
9
+
10
+ def self.handle(klass)
11
+ new(klass).handle
12
+ end
13
+
14
+ def upper(var)
15
+ @klass.class.class_variable_get(var)[@klass.class.name]
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,33 @@
1
+ require_relative 'base'
2
+
3
+ module Handlers
4
+ class Delegates < Base
5
+ def handle
6
+ delegates = upper :@@delegators
7
+ (delegates || []).each do |delegate|
8
+ Delegate.new(@klass, delegate).handle
9
+ end
10
+ end
11
+ end
12
+
13
+ class Delegate < Base
14
+ def initialize(klass, delegate)
15
+ @delegate = delegate
16
+
17
+ @form = @delegate[:form]
18
+ @foreign_key = @delegate[:foreign_key]
19
+ @relation = @delegate[:relation]
20
+ @attributes = @delegate[:attributes]
21
+
22
+ super(klass)
23
+ end
24
+
25
+ def handle
26
+ @attributes = @raw_params.slice(*@attributes).merge({
27
+ @foreign_key => @resource.id
28
+ })
29
+
30
+ @form.new(@attributes, @resource.send(@relation)).save!
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,8 @@
1
+ module Handlers
2
+ class Initializer
3
+ def self.handle(klass)
4
+ params = klass.instance_variable_get(:@params)
5
+ klass.instance_variable_set('@raw_params', {}.merge(params).freeze)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,53 @@
1
+ require_relative 'base'
2
+
3
+ module Handlers
4
+ class Polymorphs < Base
5
+ def handle
6
+ polymorphs = upper :@@polymorphic_keys
7
+ (polymorphs || []).each do |polymorph|
8
+ Polymorph.new(@klass, polymorph).handle
9
+ end
10
+ end
11
+ end
12
+
13
+ class Polymorph < Base
14
+ # Handle either the retrieving of the associated relation
15
+ # or
16
+ # the creation of the resource based on this possible input and the params
17
+ #
18
+ # Params:
19
+ # +klass+:: ActiveFormObject::Base instance
20
+ # +polymorph+:: The param specified in the dsl, example :
21
+ # {
22
+ # key: :content,
23
+ # foreign_key: :program_id,
24
+ # types: {
25
+ # polymorph: Dsl::PolymorphsTest::PolymorphForeignForm
26
+ # }
27
+ # }
28
+ #
29
+ def initialize(klass, polymorph)
30
+ @polymorph = polymorph
31
+ super(klass)
32
+ end
33
+
34
+ def handle
35
+ @params_to_send = @params[@polymorph[:key]] || {}
36
+ polymorph_instance = form_class.new(@params_to_send, @resource.try(@polymorph[:key])).save!
37
+
38
+ @params["#{@polymorph[:key]}_id".to_sym] = polymorph_instance.id
39
+ @params["#{@polymorph[:key]}_type".to_sym] = polymorph_instance.class.name
40
+ @params.delete(@polymorph[:key])
41
+ end
42
+
43
+ def form_class
44
+ @polymorph[:types][
45
+ @resource.try("#{@polymorph[:key]}_type".to_sym) || clean_params.try(:to_sym)
46
+ ]
47
+ end
48
+
49
+ def clean_params
50
+ @params_to_send.delete(:type)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,12 @@
1
+ require_relative 'base'
2
+
3
+ module Handlers
4
+ class Relations < Base
5
+ def affect_relation_values!
6
+ relation_keys = upper(:@@relation_keys) || {}
7
+ {}.merge(@params).each_key do |key|
8
+ @params["#{key}_id".to_sym] = @params[key.to_sym].id if relation_keys.include?(key)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ require_relative 'base'
2
+
3
+ module Handlers
4
+ class Resource < Base
5
+ def handle
6
+ class_resource = upper(:@@resource)
7
+ @resource ||= class_resource.try(:call, @params).try(:new)
8
+
9
+ @klass.instance_variable_set(:@resource, @resource)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,42 @@
1
+ require 'active_support'
2
+ require 'active_record'
3
+
4
+ require_relative 'base'
5
+ require_relative 'polymorphs'
6
+ require_relative 'delegates'
7
+
8
+ module Handlers
9
+ class Savings < Base
10
+ def save!(&block)
11
+ # ActiveRecord::Base.transaction do
12
+ @klass.validate!
13
+
14
+ before_save_hooks!
15
+ block ? save_with_block!(block) : save_without_block!
16
+ after_save_hooks!
17
+
18
+ @resource
19
+ # end
20
+ rescue ActiveRecord::RecordInvalid => e
21
+ e.record.errors.add(e.record.class.name, '')
22
+ raise ActiveRecord::RecordInvalid.new(e.record)
23
+ end
24
+
25
+ def after_save_hooks!
26
+ Delegates.handle(@klass)
27
+ end
28
+
29
+ def save_with_block!(block)
30
+ @klass.instance_eval(&block)
31
+ @resource.try(:save!)
32
+ end
33
+
34
+ def save_without_block!
35
+ @resource.update!(@params)
36
+ end
37
+
38
+ def before_save_hooks!
39
+ Polymorphs.handle(@klass)
40
+ end
41
+ end
42
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_form_objects
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 1.0.0.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michaël Villeneuve
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '4.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activerecord
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '4.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '4.2'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: activemodel
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -45,8 +59,20 @@ extensions: []
45
59
  extra_rdoc_files: []
46
60
  files:
47
61
  - lib/active_form_objects.rb
48
- - lib/concerns/relations.rb
49
- - lib/concerns/savings.rb
62
+ - lib/dsl/attributes.rb
63
+ - lib/dsl/delegates.rb
64
+ - lib/dsl/polymorphs.rb
65
+ - lib/dsl/relations.rb
66
+ - lib/dsl/resource.rb
67
+ - lib/dsl/savings.rb
68
+ - lib/handlers/attributes.rb
69
+ - lib/handlers/base.rb
70
+ - lib/handlers/delegates.rb
71
+ - lib/handlers/initializer.rb
72
+ - lib/handlers/polymorphs.rb
73
+ - lib/handlers/relations.rb
74
+ - lib/handlers/resource.rb
75
+ - lib/handlers/savings.rb
50
76
  homepage: https://github.com/fidme/active_form_objects
51
77
  licenses:
52
78
  - MIT
@@ -62,9 +88,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
62
88
  version: '0'
63
89
  required_rubygems_version: !ruby/object:Gem::Requirement
64
90
  requirements:
65
- - - ">="
91
+ - - ">"
66
92
  - !ruby/object:Gem::Version
67
- version: '0'
93
+ version: 1.3.1
68
94
  requirements: []
69
95
  rubyforge_project:
70
96
  rubygems_version: 2.7.3
@@ -1,35 +0,0 @@
1
- require 'active_support'
2
- require 'active_model'
3
-
4
- module Relations
5
- extend ActiveSupport::Concern
6
-
7
- @@relation_keys = {}
8
-
9
- class RelationValidator < ActiveModel::EachValidator
10
- def validate_each(record, attribute, value)
11
- record.errors.add(attribute, "#{attribute} or #{attribute}_id is required") unless record.try(attribute).present? || record.try("#{attribute}_id".to_sym).present?
12
- end
13
- end
14
-
15
- def affect_relation_values(params)
16
- @relation_keys = @@relation_keys[self.class.name] || []
17
- params.keys.each do |key|
18
- params["#{key}_id".to_sym] = params[key.to_sym].id if @relation_keys.include?(key)
19
- end
20
-
21
- params
22
- end
23
-
24
- class_methods do
25
- def relations(*params)
26
- validates *params, relation: true
27
-
28
- params.each do |param|
29
- relation_key = "#{param}_id".to_sym
30
- send(:attributes, param, relation_key)
31
- @@relation_keys[name] = (@@relation_keys[name] || []) + [param]
32
- end
33
- end
34
- end
35
- end
@@ -1,71 +0,0 @@
1
- require 'active_support'
2
-
3
- module Savings
4
- extend ActiveSupport::Concern
5
-
6
- @@associated_forms = {}
7
-
8
- class_methods do
9
- def associated(key, form, params = nil)
10
- @@associated_forms[name] ||= []
11
- @@associated_forms[name] << { name: key, form: form, params: params }
12
-
13
- set_default value: {}, to: key
14
- end
15
-
16
- def save(&block)
17
- define_method(:save!) do
18
- with_rescue do
19
- ActiveRecord::Base.transaction do
20
- validate!
21
- instance_eval(&block)
22
- @resource.try(:save!)
23
- end
24
- @resource
25
- end
26
- end
27
- end
28
- end
29
-
30
- def save!
31
- with_rescue do
32
- if @@associated_forms[self.class.name].nil?
33
- validate!
34
- @resource.update!(@params)
35
- @resource
36
- else
37
- save_associated_forms!
38
- end
39
- end
40
- end
41
-
42
- def save
43
- save!
44
- rescue
45
- false
46
- end
47
-
48
- def save_associated_forms!
49
- (@@associated_forms[self.class.name] || []).each do |associated|
50
- params = associated[:params].nil? ? @params[associated[:name]] : send(associated[:params])
51
- resource_to_save = send("#{associated[:name]}_to_update") rescue nil
52
- @TheForm = associated[:form]
53
-
54
- saved_form = @TheForm.new(params, resource_to_save).save!
55
- instance_variable_set("@#{associated[:name]}", saved_form)
56
- end
57
- end
58
-
59
- def set_associated_forms
60
- (@@associated_forms[self.class.name] || []).each do |form|
61
- instance_variable_set("@#{form[:name]}_form", form[:form])
62
- end
63
- end
64
-
65
- def with_rescue
66
- yield
67
- rescue ActiveRecord::RecordInvalid => e
68
- e.record.errors.add(e.record.class.name, '')
69
- raise ActiveRecord::RecordInvalid.new(e.record)
70
- end
71
- end