legatus 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: fd9586b50f1209e599a2c6da395c11a0be0926bee165f0d0a1046330cf844ed1
4
+ data.tar.gz: ad18c8452d8f52170fc04880f6d0370e6af3f956faa49bb1ba6021d13f502d83
5
+ SHA512:
6
+ metadata.gz: 226fa1d9f2d5f3168bbe4cdd3420513ceeeac36434490166555990eac2a44bed98dab8e81075fbdb85bb10f31cf90743abe9761432665261d4f0c6f57c590aa4
7
+ data.tar.gz: 89eef7866335b9ef6dcaea661f85643087f430e81cb8fd2a28b3bd73897080cfd34bbbe50210581696a05b922df15e4f45f145d81e3ec997d18222e4cca2aa26
@@ -0,0 +1,20 @@
1
+ Copyright 2018 rcpedro
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,28 @@
1
+ # Legatus
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'legatus'
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install legatus
22
+ ```
23
+
24
+ ## Contributing
25
+ Contribution directions go here.
26
+
27
+ ## License
28
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,27 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Legatus'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ require 'bundler/gem_tasks'
18
+
19
+ require 'rake/testtask'
20
+
21
+ Rake::TestTask.new(:test) do |t|
22
+ t.libs << 'test'
23
+ t.pattern = 'test/**/*_test.rb'
24
+ t.verbose = false
25
+ end
26
+
27
+ task default: :test
@@ -0,0 +1,11 @@
1
+ require 'legatus/railtie'
2
+ require 'legatus/extensions/hash'
3
+ require 'legatus/chain'
4
+ require 'legatus/repository'
5
+ require 'legatus/unit_of_work'
6
+ require 'legatus/directive'
7
+
8
+
9
+ module Legatus
10
+ # Your code goes here...
11
+ end
@@ -0,0 +1,24 @@
1
+ module Legatus
2
+ class Chain
3
+ attr_reader :invocations
4
+
5
+ def initialize(invocations)
6
+ @invocations = invocations
7
+ end
8
+
9
+ def apply(source)
10
+ result = source
11
+ @invocations.each do |name, params|
12
+ break if result.nil?
13
+
14
+ if params.is_a?(Proc)
15
+ result = result.send(name, &params)
16
+ else
17
+ result = result.send(name, *params)
18
+ end
19
+ end
20
+
21
+ return result
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,179 @@
1
+ require 'flexcon'
2
+
3
+
4
+ module Legatus
5
+ class Directive
6
+ extend ActiveModel::Naming
7
+
8
+ class << self
9
+ attr_reader :properties,
10
+ :models,
11
+ :validations,
12
+ :transactions,
13
+ :callbacks
14
+
15
+ def props
16
+ schema = yield
17
+
18
+ @properties = {}
19
+ schema.each do |key, invocations|
20
+ @properties[key] = Chain.new(invocations)
21
+ end
22
+ end
23
+
24
+ def permit(parent, attributes, subschema=nil)
25
+ result = parent.permit(attributes)
26
+ result.tap do |whitelisted|
27
+ subschema.each do |key, allowed|
28
+ child = parent[key]
29
+ next if child.nil?
30
+
31
+ if child.is_a?(Array)
32
+ whitelisted[key] = child.map { |c| c.permit(allowed) }
33
+ else
34
+ whitelisted[key] = child.permit(allowed)
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ def model(mname, &block)
41
+ @models ||= {}
42
+ @models[mname] = block
43
+ end
44
+
45
+ def validate(*models)
46
+ @validations ||= []
47
+ @validations.concat(models)
48
+ end
49
+
50
+ def transaction(&block)
51
+ @transactions ||= []
52
+ @transactions << block
53
+ end
54
+
55
+ def callback
56
+ @callbacks ||= {}
57
+ @callbacks.merge!(yield)
58
+ end
59
+ end
60
+
61
+ attr_reader :props, :params, :errors
62
+
63
+ def initialize(params)
64
+ @params = params
65
+ @errors = {}
66
+ @props = {}
67
+
68
+ self.class.properties.each do |pname, chain|
69
+ @props[pname] = chain.apply(params)
70
+ end
71
+ end
72
+
73
+ def valid?
74
+ return @errors.empty?
75
+ end
76
+
77
+ def invalid?
78
+ return !@errors.empty?
79
+ end
80
+
81
+ def extract(*props)
82
+ props.map { |prop| self.send(prop) }
83
+ end
84
+
85
+ def clean
86
+ self.reqs(self.props, self.props.keys)
87
+ end
88
+
89
+ def load
90
+ self.valid? and self.class.models.each do |mname, loader|
91
+ self.send(:"#{mname}=", Flexcon.dispatch(self, loader))
92
+ end
93
+ end
94
+
95
+ def validate
96
+ self.valid? and self.class.validations.each do |mname|
97
+ self.check(mname => self.send(mname))
98
+ end if self.class.validations.present?
99
+
100
+ self.valid? and self.class.models.each do |mname, loader|
101
+ self.check(mname => self.send(mname))
102
+ end if self.class.models.present?
103
+ end
104
+
105
+ def persist
106
+ self.valid? and UnitOfWork.transaction do |uow|
107
+ self.class.transactions.each do |handler|
108
+ handler.call(uow, self)
109
+ end
110
+ end
111
+ end
112
+
113
+ def execute
114
+ return (
115
+ self.valid? and
116
+ self.executed?(:clean) and
117
+ self.executed?(:load) and
118
+ self.executed?(:validate) and
119
+ self.executed?(:persist)
120
+ )
121
+ end
122
+
123
+ protected
124
+ def chain(obj, invocations)
125
+ return Chain.new(invocations).apply(obj)
126
+ end
127
+
128
+ def reqs(source, attributes)
129
+ attributes.each do |attribute|
130
+ next if not source[attribute].blank?
131
+ @errors[attribute] ||= {}
132
+ @errors[attribute][:base] = []
133
+ @errors[attribute][:base] << 'is required'
134
+ end
135
+ end
136
+
137
+ def executed?(stepname)
138
+ return (
139
+ self.callback?(stepname, :before) and
140
+ self.send(stepname) and
141
+ self.callback?(stepname, :after)
142
+ )
143
+ end
144
+
145
+ def callback?(mname, stage)
146
+ return true if self.class.callbacks.blank?
147
+ return true if self.class.callbacks[mname].blank?
148
+
149
+ Flexcon.dispatch(self, self.class.callbacks[mname][stage])
150
+ end
151
+
152
+ def check(schema)
153
+ schema.each do |key, model|
154
+ if model.respond_to?(:each_with_index)
155
+ self.check_many(key, model)
156
+ else
157
+ self.check_one(key, model)
158
+ end
159
+ end
160
+ end
161
+
162
+ def check_one(key, model)
163
+ if model.invalid?
164
+ @errors[key] ||= {}
165
+ @errors[key].merge!(model.errors)
166
+ end
167
+ end
168
+
169
+ def check_many(key, models)
170
+ models.each_with_index do |m, i|
171
+ if m.invalid?
172
+ @errors[key] ||= {}
173
+ @errors[key][i] ||= {}
174
+ @errors[key][i].merge!(m.errors)
175
+ end
176
+ end
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,5 @@
1
+ class Hash
2
+ def permit(*keys)
3
+ self.slice(keys)
4
+ end
5
+ end
@@ -0,0 +1,4 @@
1
+ module Legatus
2
+ class Railtie < ::Rails::Railtie
3
+ end
4
+ end
@@ -0,0 +1,25 @@
1
+ module Legatus
2
+ module Repository
3
+ extend ActiveSupport::Concern
4
+
5
+ class_methods do
6
+ def find_and_init(filters, attributes=nil)
7
+ instance = self.find_by(filters)
8
+ instance ||= self.new
9
+
10
+ attributes ||= filters
11
+ instance.assign_attributes(attributes)
12
+
13
+ return instance
14
+ end
15
+
16
+ def find_or_init(filters, attributes)
17
+ instance = self.find_by(filters)
18
+ return if instance.present?
19
+
20
+ instance = self.new
21
+ instance.assign_attributes(attributes)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,36 @@
1
+ module Legatus
2
+ class UnitOfWork
3
+
4
+ def self.transaction
5
+ ActiveRecord::Base.connection.transaction do
6
+ yield(UnitOfWork.new)
7
+ end
8
+ end
9
+
10
+ def save(*models)
11
+ models.all? { |model| model.save }
12
+ end
13
+
14
+ def update(*models)
15
+ models.all? { |model| model.update }
16
+ end
17
+
18
+ def create(*models)
19
+ models.all? { |model| model.create }
20
+ end
21
+
22
+ def destroy(*models)
23
+ models.all? { |model| model.destroy }
24
+ end
25
+
26
+ def persist(*models)
27
+ models.all? do |model|
28
+ if model.marked_for_destruction?
29
+ model.destroy
30
+ else
31
+ model.save
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,3 @@
1
+ module Legatus
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :legatus do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: legatus
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - rcpedro
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-09-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 5.2.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 5.2.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: flexcon
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.1.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.1.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: sqlite3
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Declare busness directives for actions in Rails.
56
+ email:
57
+ - rodettecpedro@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - MIT-LICENSE
63
+ - README.md
64
+ - Rakefile
65
+ - lib/legatus.rb
66
+ - lib/legatus/chain.rb
67
+ - lib/legatus/directive.rb
68
+ - lib/legatus/extensions/hash.rb
69
+ - lib/legatus/railtie.rb
70
+ - lib/legatus/repository.rb
71
+ - lib/legatus/unit_of_work.rb
72
+ - lib/legatus/version.rb
73
+ - lib/tasks/legatus_tasks.rake
74
+ homepage: https://github.com/rcpedro/legatus
75
+ licenses:
76
+ - MIT
77
+ metadata: {}
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubyforge_project:
94
+ rubygems_version: 2.7.7
95
+ signing_key:
96
+ specification_version: 4
97
+ summary: Rails Business Directives
98
+ test_files: []