active_form_objects 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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