active_form_objects 1.1.0 → 2.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1277569aeb69dcb5cf7505976dbea68d1f6083aaa2df4574e5dc7937890eaff2
4
- data.tar.gz: 16f628ba1c7206c8f22b419499dd517f434c0f56720aafc27830da498dca66ee
3
+ metadata.gz: 8b5ee38f5092d2cb6590e7fb237b5c578e62cef571cb677257304a6c7f72f271
4
+ data.tar.gz: f6391721dc190de74fdf20e3a7d08a018dbdb6cc96dd460fe5eaf20c0df0836a
5
5
  SHA512:
6
- metadata.gz: 5dc8b54bc4e427b897d45131d57d2e72014b6f1baf64b48f72d33933ae1b8c537b8d5b94fd4c3e77b73e382f1ef1a1df97310307ccafee99e0263528e52470dc
7
- data.tar.gz: 1dde523dcf396183a2b8f946992c0ee9f5ce70fcecc5770eec05b080e0f974d687dfe4794f93bd3bfe59581405e4431594d14a07c29e9b26f8d4db73e84a1cb6
6
+ metadata.gz: de2a9c8359c493a530c48a37a5db6e226ae6e7c75fdb4833f029c88fd0be2ae09646bb66acc08477a897bc2ee51057685fdb117f8e21c61f1baf9b3d15b70336
7
+ data.tar.gz: de1dcfd0387febc4f01aa471248d150790039e10349e0f3d57ceec3c4b8e6e96ad80f336b9d56e2fc7e97dca53c70cd4941821676ed21d4058f4954fc6b5ed4d
@@ -1,46 +1,52 @@
1
1
  require 'active_model'
2
2
  require 'active_support/core_ext/hash/indifferent_access'
3
3
 
4
-
4
+ require_relative 'dsl/debug'
5
5
  require_relative 'dsl/relations'
6
6
  require_relative 'dsl/attributes'
7
7
  require_relative 'dsl/delegates'
8
8
  require_relative 'dsl/savings'
9
9
  require_relative 'dsl/resource'
10
- require_relative 'dsl/associates'
11
10
  require_relative 'dsl/polymorphs'
11
+ require_relative 'dsl/scopes'
12
+ require_relative 'dsl/hooks'
12
13
 
14
+ require_relative 'handlers/base'
13
15
  require_relative 'handlers/initializer'
16
+ require_relative 'handlers/debug'
14
17
  require_relative 'handlers/inheritance'
15
18
  require_relative 'handlers/relations'
16
19
  require_relative 'handlers/resource'
17
20
  require_relative 'handlers/attributes'
18
- require_relative 'handlers/associates'
19
21
 
20
22
  module ActiveFormObjects
21
23
  class Base
22
24
  include ActiveModel::Model
23
25
 
26
+ include Dsl::Debug
24
27
  include Dsl::Resource
25
28
  include Dsl::Attributes
26
29
  include Dsl::Relations
27
30
  include Dsl::Polymorphs
28
31
  include Dsl::Delegates
29
- include Dsl::Associates
30
32
  include Dsl::Savings
33
+ include Dsl::Scopes
34
+ include Dsl::Hooks
31
35
 
32
36
  def self.inherited(subclass)
33
37
  Handlers::Inheritance.handle(subclass, self)
34
38
  end
35
39
 
36
40
  def initialize(params, resource = nil)
41
+ raise ActiveFormObjects::HandlerError, "[#{self.class.name}] params were not correclty declared" unless params.is_a?(Hash)
42
+
37
43
  @params = params.with_indifferent_access
38
44
  @resource = resource
39
45
 
40
46
  Handlers::Initializer.handle(self)
41
- Handlers::Associates.handle(self)
42
47
  Handlers::Resource.handle(self)
43
48
  Handlers::Attributes.handle(self)
49
+ Handlers::Debug.handle(self)
44
50
  super(@params)
45
51
  end
46
52
  end
@@ -1,5 +1,6 @@
1
1
  require 'active_support'
2
2
  require 'active_support/core_ext/hash/indifferent_access'
3
+ require_relative 'errors'
3
4
 
4
5
  module Dsl
5
6
  module Attributes
@@ -22,11 +23,15 @@ module Dsl
22
23
  attr_accessor :params
23
24
 
24
25
  def self.attributes(*params)
26
+ raise ActiveFormObjects::DslError.new("[#{self.name}] attributes must not be empty") if params.empty?
27
+
25
28
  @@attributes[name] = (@@attributes[name] || []) + params
26
29
  attr_accessor(*params)
27
30
  end
28
31
 
29
32
  def self.set_default(params)
33
+ raise ActiveFormObjects::DslError.new("[#{self.name}] set_default must be declared like { value: 'the default', to: :the_attribute }") if params[:to].nil? || params[:value].nil?
34
+
30
35
  [params[:to]].flatten.each do |param|
31
36
  @@default_params[name] ||= {}
32
37
  @@default_params[name][param] = params[:value]
@@ -42,10 +47,12 @@ module Dsl
42
47
  end
43
48
 
44
49
  def self.prepare(*params)
45
- method_to_call = params.last[:with]
50
+ raise ActiveFormObjects::DslError.new("[#{self.name}] prepare takes a lambda as second argument, not a #{params.last.class.name}") if !params.last.respond_to?(:call)
51
+
52
+ lambda_to_call = params.last
46
53
  @@preparers[name] = (@@preparers[name] || []) + [{
47
54
  key: params.first,
48
- method_to_call: method_to_call
55
+ lambda: lambda_to_call
49
56
  }]
50
57
  end
51
58
  end
data/lib/dsl/debug.rb ADDED
@@ -0,0 +1,14 @@
1
+ require 'active_support'
2
+
3
+ module Dsl
4
+ module Debug
5
+ extend ActiveSupport::Concern
6
+
7
+ @@debug = {}
8
+ included do
9
+ def self.debug
10
+ @@debug[name] = true
11
+ end
12
+ end
13
+ end
14
+ end
data/lib/dsl/errors.rb ADDED
@@ -0,0 +1,4 @@
1
+ module ActiveFormObjects
2
+ class DslError < RuntimeError
3
+ end
4
+ end
data/lib/dsl/hooks.rb ADDED
@@ -0,0 +1,29 @@
1
+ require 'active_support'
2
+ require 'active_model'
3
+
4
+ module Dsl
5
+ module Hooks
6
+ extend ActiveSupport::Concern
7
+
8
+ @@before_save = {}
9
+ @@after_save = {}
10
+ @@after_validation = {}
11
+
12
+ class_methods do
13
+ def before_save(*params, &block)
14
+ hooks = block.present? ? [block] : params
15
+ @@before_save[name] = (@@before_save[name] || []) + hooks
16
+ end
17
+
18
+ def after_save(*params, &block)
19
+ hooks = block.present? ? [block] : params
20
+ @@after_save[name] = (@@after_save[name] || []) + hooks
21
+ end
22
+
23
+ def after_validation(*params, &block)
24
+ hooks = block.present? ? [block] : params
25
+ @@after_validation[name] = (@@after_validation[name] || []) + hooks
26
+ end
27
+ end
28
+ end
29
+ end
data/lib/dsl/resource.rb CHANGED
@@ -8,8 +8,10 @@ module Dsl
8
8
 
9
9
  included do
10
10
  attr_reader :resource
11
-
11
+
12
12
  def self.resource(resource = nil, &block)
13
+ raise ActiveFormObjects::DslError.new("[#{self.name}] resource has been incorrectly declared") if (resource.nil? && block.nil?) || (block.nil? && !resource.respond_to?(:all))
14
+
13
15
  bloc_to_call = block || proc { resource }
14
16
  @@resource[name] = bloc_to_call
15
17
  end
data/lib/dsl/scopes.rb ADDED
@@ -0,0 +1,33 @@
1
+ require 'active_support'
2
+ require 'rubygems'
3
+ require 'method_source'
4
+ require 'ruby2ruby'
5
+ require 'ruby_parser'
6
+
7
+ module Dsl
8
+ module Scopes
9
+ extend ActiveSupport::Concern
10
+
11
+ @@scopes = {}
12
+
13
+ included do
14
+ def self.scope(*params, &block)
15
+ raise(ActiveFormObjects::DslError, "[#{name}] scope must be a bloc") if block.nil? || !block.respond_to?(:call)
16
+
17
+ params.each do |param|
18
+ block_content = Ruby2Ruby.new.process(RubyParser.new.process(block.source).to_a.last)
19
+ eval("class ::#{name}Scope#{param.capitalize} < #{name} ; #{block_content}; end")
20
+ end
21
+ end
22
+
23
+ def self.new(params, resource = nil, options = {})
24
+ if options[:scope].present?
25
+ class_to_call = "::#{name}Scope#{options[:scope].capitalize}".constantize rescue raise(ActiveFormObjects::DslError, "[#{name}] No scope named #{options[:scope]} found")
26
+ return class_to_call.new(params, resource)
27
+ end
28
+
29
+ super(params, resource)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -23,7 +23,7 @@ module Handlers
23
23
  # DSL method : prepare
24
24
  def affect_prepared_values!
25
25
  (upper(:@@preparers) || []).each do |preparer|
26
- @params[preparer[:key]] = @params[preparer[:key]].try(preparer[:method_to_call])
26
+ @params[preparer[:key]] = preparer[:lambda].try(:call, @params[preparer[:key]])
27
27
  end
28
28
  end
29
29
 
data/lib/handlers/base.rb CHANGED
@@ -16,12 +16,12 @@ module Handlers
16
16
  end
17
17
 
18
18
  def raise_error(string)
19
- raise ActiveFormObjects::Error.new("[#{@klass.class.name}] #{string}")
19
+ raise ActiveFormObjects::HandlerError.new("[#{@klass.class.name}] #{string}")
20
20
  end
21
21
  end
22
22
  end
23
23
 
24
24
  module ActiveFormObjects
25
- class Error < RuntimeError
25
+ class HandlerError < RuntimeError
26
26
  end
27
27
  end
@@ -0,0 +1,24 @@
1
+ require_relative 'base'
2
+
3
+ module Handlers
4
+ class Debug < Base
5
+ def handle
6
+ return unless upper(:@@debug)
7
+ @output = []
8
+
9
+ build_output
10
+ end
11
+
12
+ def build_output
13
+ puts "\n==== ActiveFormObjects Debugger #{@klass.class.name} ===="
14
+ puts "\n👉 Called with\n #{@klass.class.name}.new(#{@raw_params}, #{@resource || 'nil'})"
15
+
16
+ if upper(:@@resource).nil? && @resource.nil?
17
+ puts "\n👉 No resource has been declared or given, calling save! will most likely fail."
18
+ elsif !@resource.nil?
19
+ puts "\n👉 The resource is a #{@resource.class.name}"
20
+ end
21
+ puts " @resource.update!(#{@params})\n\n"
22
+ end
23
+ end
24
+ end
@@ -28,8 +28,18 @@ module Handlers
28
28
  @foreign_key => @resource.id
29
29
  })
30
30
 
31
+ proceed_debug
32
+
31
33
  @form.new(@attributes, @resource.send(@relation)).save!
32
34
  @resource.reload
33
35
  end
36
+
37
+ def proceed_debug
38
+ return unless upper(:@@debug)
39
+
40
+ puts '👉 Processing delegate'
41
+ puts "#{@form}.new(#{@attributes}, #{@resource.send(@relation) || "nil"}).save!"
42
+ puts ""
43
+ end
34
44
  end
35
45
  end
@@ -0,0 +1,42 @@
1
+ require_relative 'base'
2
+
3
+ module Handlers
4
+ class BeforeSaveHooks < Base
5
+ def handle
6
+ handle_hooks('before_save')
7
+ end
8
+
9
+ def handle_hooks(hook_name)
10
+ (upper("@@#{hook_name}") || []).each do |method_or_block|
11
+ handle_single(method_or_block)
12
+ end
13
+ end
14
+
15
+ def handle_single(method_or_block)
16
+ raise_error('a hook seems to be nil') if method_or_block.nil?
17
+
18
+ method_or_block.respond_to?(:call) ? handle_block(method_or_block) : handle_method(method_or_block)
19
+ end
20
+
21
+ def handle_block(block)
22
+ @klass.instance_eval(&block)
23
+ end
24
+
25
+ def handle_method(method)
26
+ raise_error("could not find hook method named #{method}") unless @klass.respond_to?(method)
27
+ @klass.send(method)
28
+ end
29
+ end
30
+
31
+ class AfterSaveHooks < BeforeSaveHooks
32
+ def handle
33
+ handle_hooks('after_save')
34
+ end
35
+ end
36
+
37
+ class AfterValidationsHooks < BeforeSaveHooks
38
+ def handle
39
+ handle_hooks('after_validation')
40
+ end
41
+ end
42
+ end
@@ -5,7 +5,11 @@ module Handlers
5
5
  def affect_relation_values!
6
6
  relation_keys = upper(:@@relation_keys) || {}
7
7
  {}.merge(@params).each_key do |key|
8
- @params["#{key}_id"] = @params[key].id if relation_keys.include?(key.to_sym)
8
+ if relation_keys.include?(key.to_sym)
9
+ raise_error("relation named :#{key} must be an ActiveRecord instance not a #{@params[key].class}. Check the params you sent to this form.") unless @params[key].respond_to?(:id)
10
+
11
+ @params["#{key}_id"] = @params[key].id
12
+ end
9
13
  end
10
14
  end
11
15
  end
@@ -4,15 +4,15 @@ require 'active_record'
4
4
  require_relative 'base'
5
5
  require_relative 'polymorphs'
6
6
  require_relative 'delegates'
7
- require_relative 'associates'
7
+ require_relative 'hooks'
8
8
 
9
9
  module Handlers
10
10
  class Savings < Base
11
11
  def save!(&block)
12
12
  ActiveRecord::Base.transaction do
13
- return save_associated_forms! unless upper('@@associated_forms').nil?
14
- @klass.validate!
15
13
  before_save_hooks!
14
+ @klass.validate!
15
+ after_validations_hooks!
16
16
  block ? save_with_block!(block) : save_without_block!
17
17
  after_save_hooks!
18
18
  @resource
@@ -22,8 +22,13 @@ module Handlers
22
22
  raise ActiveRecord::RecordInvalid.new(e.record)
23
23
  end
24
24
 
25
+ def before_save_hooks!
26
+ BeforeSaveHooks.handle(@klass)
27
+ end
28
+
25
29
  def after_save_hooks!
26
30
  Delegates.handle(@klass)
31
+ AfterSaveHooks.handle(@klass)
27
32
  end
28
33
 
29
34
  def save_with_block!(block)
@@ -36,12 +41,9 @@ module Handlers
36
41
  @resource.update!(@params)
37
42
  end
38
43
 
39
- def before_save_hooks!
44
+ def after_validations_hooks!
45
+ AfterValidationsHooks.handle(@klass)
40
46
  Polymorphs.handle(@klass)
41
47
  end
42
-
43
- def save_associated_forms!
44
- Associates.new(@klass).save_associated_forms!
45
- end
46
48
  end
47
49
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_form_objects
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michaël Villeneuve
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-02-15 00:00:00.000000000 Z
11
+ date: 2019-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -52,6 +52,34 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '4.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: ruby_parser
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.1'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.1'
69
+ - !ruby/object:Gem::Dependency
70
+ name: ruby2ruby
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">"
74
+ - !ruby/object:Gem::Version
75
+ version: 2.4.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">"
81
+ - !ruby/object:Gem::Version
82
+ version: 2.4.0
55
83
  description: Clean up your controller, slim up your models, handle more use cases
56
84
  email: contact@michaelvilleneuve.fr
57
85
  executables: []
@@ -59,17 +87,21 @@ extensions: []
59
87
  extra_rdoc_files: []
60
88
  files:
61
89
  - lib/active_form_objects.rb
62
- - lib/dsl/associates.rb
63
90
  - lib/dsl/attributes.rb
91
+ - lib/dsl/debug.rb
64
92
  - lib/dsl/delegates.rb
93
+ - lib/dsl/errors.rb
94
+ - lib/dsl/hooks.rb
65
95
  - lib/dsl/polymorphs.rb
66
96
  - lib/dsl/relations.rb
67
97
  - lib/dsl/resource.rb
68
98
  - lib/dsl/savings.rb
69
- - lib/handlers/associates.rb
99
+ - lib/dsl/scopes.rb
70
100
  - lib/handlers/attributes.rb
71
101
  - lib/handlers/base.rb
102
+ - lib/handlers/debug.rb
72
103
  - lib/handlers/delegates.rb
104
+ - lib/handlers/hooks.rb
73
105
  - lib/handlers/inheritance.rb
74
106
  - lib/handlers/initializer.rb
75
107
  - lib/handlers/polymorphs.rb
@@ -1,18 +0,0 @@
1
- require 'active_support'
2
-
3
- module Dsl
4
- module Associates
5
- extend ActiveSupport::Concern
6
-
7
- @@associated_forms = {}
8
-
9
- class_methods do
10
- def associated(key, form, params = nil)
11
- @@associated_forms[name] ||= []
12
- @@associated_forms[name] << { name: key, form: form, params: params }
13
-
14
- set_default value: {}, to: key
15
- end
16
- end
17
- end
18
- end
@@ -1,23 +0,0 @@
1
- require 'active_support/core_ext/hash/reverse_merge'
2
- require_relative 'base'
3
-
4
- module Handlers
5
- class Associates < Base
6
- def handle
7
- (upper('@@associated_forms') || []).each do |form|
8
- @klass.instance_variable_set("@#{form[:name]}_form", form[:form])
9
- end
10
- end
11
-
12
- def save_associated_forms!
13
- (upper('@@associated_forms') || []).each do |associated|
14
- params = associated[:params].nil? ? @params[associated[:name]] : @klass.send(associated[:params])
15
- resource_to_save = @klass.send("#{associated[:name]}_to_update") rescue nil
16
- the_form = associated[:form]
17
-
18
- saved_form = the_form.new(params, resource_to_save).save!
19
- @klass.instance_variable_set("@#{associated[:name]}", saved_form)
20
- end
21
- end
22
- end
23
- end