eitil 0.3.1
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +272 -0
- data/Rakefile +18 -0
- data/app/controllers/eitil/application_controller.rb +4 -0
- data/app/jobs/eitil/application_job.rb +4 -0
- data/app/mailers/eitil/application_mailer.rb +6 -0
- data/app/models/eitil/application_record.rb +5 -0
- data/config/initializers/monkeys/application_controller.rb +14 -0
- data/config/initializers/monkeys/date_time.rb +7 -0
- data/config/initializers/monkeys/hash.rb +14 -0
- data/config/initializers/monkeys/kernel.rb +44 -0
- data/config/initializers/monkeys/module.rb +12 -0
- data/config/initializers/monkeys/object.rb +29 -0
- data/config/initializers/wrappers/decorators/application_decorator.rb +19 -0
- data/config/initializers/wrappers/decorators/controller_decorator.rb +63 -0
- data/config/initializers/wrappers/jobs/active_job_macros.rb +18 -0
- data/config/initializers/wrappers/jobs/single_method_job.rb +10 -0
- data/config/initializers/wrappers/routes/extended_resources.rb +40 -0
- data/config/initializers/wrappers/scopes/default_scopes.rb +60 -0
- data/config/routes.rb +2 -0
- data/lib/eitil.rb +6 -0
- data/lib/eitil/engine.rb +14 -0
- data/lib/eitil/version.rb +3 -0
- data/lib/tasks/eitil_tasks.rake +4 -0
- metadata +98 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f822863c972553dc89dca4e80fce4b197c89c27f78456342195f46b920fa07f5
|
4
|
+
data.tar.gz: 0e852adfd5a9127d3d67f349102bb6000121b730a5a42d0628b09beab45723fe
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cc64496f6e70c4d737ddf6bf091988ab01425802852034dd1d0c083bee1cda38ee25381927b498fc74c0094f27c071b71e10b360fc00ac477e81635b509d1915
|
7
|
+
data.tar.gz: ac2c18d0bd040e892caf008de55550cd09322fb69b09d15efd6adf6d147ce399b8e5aff547603af1311c7ebb86f0a8051da40211791d70042ee4e87a57ef23b3
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2021 Jurriaan Schrofer
|
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.
|
data/README.md
ADDED
@@ -0,0 +1,272 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
|
4
|
+
# Eitil (Eitje Util)
|
5
|
+
|
6
|
+
Never stops increasing your life's efficacy and productivity, yay!
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
|
16
|
+
gem 'eitil', git: 'https://github.com/eitje-app/eitil_engine', branch: 'production'
|
17
|
+
|
18
|
+
```
|
19
|
+
|
20
|
+
Or this line, with your own path correctly set, for development purposes:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
|
24
|
+
gem 'eitil', path: "/Users/jurriaanschrofer/Documents/eitil"
|
25
|
+
|
26
|
+
```
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
# Monkey patches
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
## Kernel
|
35
|
+
|
36
|
+
```ruby
|
37
|
+
all_args_to_ivars(binding)
|
38
|
+
# sets all keywords arguments of the method's local binding to instance variables
|
39
|
+
# call as: all_args_to_ivars binding
|
40
|
+
|
41
|
+
args_to_ivars(binding, *local_vars)
|
42
|
+
# sets specified keywords arguments of the method's local binding to instance variables
|
43
|
+
# call as: all_args_to_ivars binding :user_id, :user_name
|
44
|
+
|
45
|
+
all_kwargs_to_ivars(binding)
|
46
|
+
# sets the method's **kwargs argument to instance variables, with each key as the ivar's "@#{name}" and the value as its value
|
47
|
+
# call as: kwargs_to_ivars binding
|
48
|
+
|
49
|
+
set_ivars(*ivars)
|
50
|
+
# sets instance variables named @"#{ivar}" for each symbol passed, by invoking send("set_#{ivar}")
|
51
|
+
# e.g. set_ivars(:user) sets @user with the value returned by your local method .set_user
|
52
|
+
# call as: set_ivars :user, :authentication, :connection
|
53
|
+
|
54
|
+
safe_send(method, *args, return_value: nil)
|
55
|
+
# a safe version of .send, which in case of an error rescues and returns return_value (default: nil) instead
|
56
|
+
|
57
|
+
safe_call(*args, return_value: nil, &block)
|
58
|
+
# a safe version of .call, which in case of an error rescues and returns return_value (default: nil) instead
|
59
|
+
# accepts either a proc argument or a block
|
60
|
+
|
61
|
+
raise_error(_class_name, message = nil)
|
62
|
+
# creates an error class if currently undefined, inheriting from StandardError, and raises the error with the given message
|
63
|
+
# call as: raise_error "SomethingWentWrongError", "check your code, bro!"
|
64
|
+
# => SomethingWentWrongError (check your code, bro!)
|
65
|
+
```
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
## Object
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
all_methods(include_ancestors = true, grep: nil)
|
73
|
+
# pretty prints all methods for any object, grouped per type (e.g. private_methods, public_instance_methods)
|
74
|
+
# call as: Class.all_methods false, grep: /json/
|
75
|
+
```
|
76
|
+
|
77
|
+
|
78
|
+
|
79
|
+
## Module
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
include_concerns_of(*directories)
|
83
|
+
# includes all models/concerns/{sub_directory}/* within a module or class
|
84
|
+
# call as: include_concerns_of :user, :mail
|
85
|
+
# => includes all modules of models/concerns/user/* and models/oncerns/mail/*
|
86
|
+
```
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
## Hash
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
auto_dig(_hash = self, _key)
|
94
|
+
# finds the value for the given hash key, irregardless of the amount of nested layers
|
95
|
+
# call as: {a: 1, b: {c: 2, d: {e: 3}}}.auto_dig :e
|
96
|
+
# => 3
|
97
|
+
```
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
## ApplicationController
|
102
|
+
|
103
|
+
```ruby
|
104
|
+
slice_params(*args)
|
105
|
+
# slices request params, converts them to JSON and symbolizes the keys
|
106
|
+
# call as: slice_params :id, :user
|
107
|
+
# => { id: 1, user: 69 }
|
108
|
+
```
|
109
|
+
|
110
|
+
|
111
|
+
|
112
|
+
## DateTime
|
113
|
+
|
114
|
+
```ruby
|
115
|
+
prettify
|
116
|
+
# formats DateTime instances into a pretty, simple and filename friendly format
|
117
|
+
# call as: DateTime.now.prettify
|
118
|
+
# => "2021-04-21.17:51:42"
|
119
|
+
```
|
120
|
+
|
121
|
+
|
122
|
+
|
123
|
+
# Wrappers
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
## Decorators
|
128
|
+
|
129
|
+
### Info
|
130
|
+
|
131
|
+
The Eitil decorator wrappers help you to standardize the calling of the right decorator method from within your controller action. Basically it provides you with a decorate macro in each controller.
|
132
|
+
|
133
|
+
### Decorate Macro
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
decorate(dec_item, dec_method: nil, dec_class: nil, **dec_kwargs)
|
137
|
+
```
|
138
|
+
|
139
|
+
- dec_item is the instance that will be decorated
|
140
|
+
- dec_method enabled you to set the desired decorator method. If not provided, it will look into the request params: if params["isMobile"] is present it will call .app, if params["isWeb"] is present it will call :app. If neither is provided in the params, it will call the default method :base.
|
141
|
+
- dec_class enables you to overwrite the decorator class that will be called. If not provided, the decorator class will be inferred from the instance model's classname (User => UserDecorator).
|
142
|
+
- dec_kwargs enables you to provide additional arguments, which will be passed to your decorator method.
|
143
|
+
|
144
|
+
### Configuration
|
145
|
+
|
146
|
+
1. Your decorator classes should inherit from Eitil::ApplicationDecorator.
|
147
|
+
2. Your controllers should inherit the module Eitil::ControllerDecorator, through inclusion in a superclass.
|
148
|
+
3. If you set controller ivars for each request, you can make them available in your decorators by providing Eitil a method which returns the names of your ivars as an array of symbols:
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
# initializers/eitil.rb
|
152
|
+
|
153
|
+
Eitil.set_config do |config|
|
154
|
+
config.get_controller_ivars_method = 'API::VerlofVerzoekenController.controller_ivars' # => [:user, :env]
|
155
|
+
end
|
156
|
+
```
|
157
|
+
|
158
|
+
|
159
|
+
|
160
|
+
## Router
|
161
|
+
|
162
|
+
### Info
|
163
|
+
|
164
|
+
The Eitil router wrapper enables you to easily create new routes that can be shared among controllers. In that sense, it is as a custom extension of the built-in resourceful routes.
|
165
|
+
|
166
|
+
### Create New Route Macro
|
167
|
+
|
168
|
+
The first macro, new_route, enables you to create new route objects which may be called and used by different controllers.
|
169
|
+
|
170
|
+
```ruby
|
171
|
+
# config/routes.rb
|
172
|
+
|
173
|
+
new_route(verb, _method, action, scope)
|
174
|
+
# call as: new_route :post, :attachment, "add_attachment", :member
|
175
|
+
```
|
176
|
+
|
177
|
+
- verb refers to the http_verb, e.g. :put.
|
178
|
+
- method refers to the given http method (e.g. 'users/:id'). Additionally, this is the name you will refer to in order to include the route into a controller. Therefore the argument should be unique among all other routes.
|
179
|
+
- action refers to the controller action to which you want to redirect to request, e.g. :update_user.
|
180
|
+
- scope refers to the url and can be set to either :member or :collection.
|
181
|
+
|
182
|
+
### Add Routes Macro
|
183
|
+
|
184
|
+
The second macro, extended_resources, enables you to create all standard resources for a controller and add your own standardized routes. This macro works the same as the built-in :resources, except that you can pass more arguments to only: [], which adds the routes to your controller.
|
185
|
+
|
186
|
+
```ruby
|
187
|
+
# config/routes.rb
|
188
|
+
|
189
|
+
extended_resources(controller, **kwargs)
|
190
|
+
# call as: extended_resources :posts, only: [:create, :update, :attachment]
|
191
|
+
|
192
|
+
```
|
193
|
+
|
194
|
+
### Configuration
|
195
|
+
|
196
|
+
The router wrapper is a single module which is automatically included into your application's router file, therefore no configuration is required.
|
197
|
+
|
198
|
+
|
199
|
+
|
200
|
+
## Jobs
|
201
|
+
|
202
|
+
### Info
|
203
|
+
|
204
|
+
The Eitil jobs wrapper enables you to create perform_later jobs on the fly, without the need to create a new class and file. The macro new_job accepts a :method as argument and defines a new method :method_job. The newly defined :method_job, when called, performs the orginal :method in the background. The new_job macro accepts both instance methods and singleton methods, which are defined within there own method scope.
|
205
|
+
|
206
|
+
### Job Macro
|
207
|
+
|
208
|
+
```ruby
|
209
|
+
new_job(_method)
|
210
|
+
# assuming a method :print_hello_world, call as: new_job :hello_world
|
211
|
+
# => method :hello_world_job
|
212
|
+
```
|
213
|
+
|
214
|
+
- method is
|
215
|
+
|
216
|
+
### Configuration
|
217
|
+
|
218
|
+
The new_job macro is monkey patched into Kernel, therefore no configuration is required.
|
219
|
+
|
220
|
+
|
221
|
+
|
222
|
+
## Scopes
|
223
|
+
|
224
|
+
### Info
|
225
|
+
|
226
|
+
The Eitil scopes wrapper creates various default scopes for a model, simply through including 'use_eitil_scopes' in the top of your model file, for example:
|
227
|
+
|
228
|
+
```ruby
|
229
|
+
# models/user.rb
|
230
|
+
|
231
|
+
class User < ApplicationRecord
|
232
|
+
use_eitil_scopes
|
233
|
+
end
|
234
|
+
```
|
235
|
+
|
236
|
+
### The Scopes
|
237
|
+
|
238
|
+
Scopes are generated through the columns of your model's database table. Which scopes are generated depends on the datatype of a column. For example, if your User model with table users has a column is_manager, a scope :is_manager_true is generated for your User model. A scope method is defined only if it does not already responds to another method of the same name. The scopes generated are:
|
239
|
+
|
240
|
+
```ruby
|
241
|
+
# columns of datatype: boolean
|
242
|
+
.{column_name}_true
|
243
|
+
.{column_name}_false
|
244
|
+
|
245
|
+
# columns of datatype: datetime
|
246
|
+
.{column_name}_today
|
247
|
+
.{column_name}_past
|
248
|
+
.{column_name}_future
|
249
|
+
.{column_name}_on_date(date)
|
250
|
+
.{column_name}_before_date(date)
|
251
|
+
.{column_name}_after_date(date)
|
252
|
+
.{column_name}_between_dates(start_date, end_date)
|
253
|
+
.{column_name}_oldest_first
|
254
|
+
.{column_name}_newest_first
|
255
|
+
|
256
|
+
# columns of datatype: date
|
257
|
+
.{column_name}_today
|
258
|
+
.{column_name}_past
|
259
|
+
.{column_name}_future
|
260
|
+
.{column_name}_on_date(date)
|
261
|
+
.{column_name}_before_date(date)
|
262
|
+
.{column_name}_after_date(date)
|
263
|
+
.{column_name}_between_dates(start_date, end_date)
|
264
|
+
.{column_name}_oldest_first
|
265
|
+
.{column_name}_newest_first
|
266
|
+
```
|
267
|
+
|
268
|
+
### Configuration
|
269
|
+
|
270
|
+
Your models should inherit the module Eitil::DefaultScopes through inclusion in a superclass, such as ApplicationRecord.
|
271
|
+
|
272
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
|
3
|
+
APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
|
4
|
+
load "rails/tasks/engine.rake"
|
5
|
+
|
6
|
+
load "rails/tasks/statistics.rake"
|
7
|
+
|
8
|
+
require "bundler/gem_tasks"
|
9
|
+
|
10
|
+
require "rake/testtask"
|
11
|
+
|
12
|
+
Rake::TestTask.new(:test) do |t|
|
13
|
+
t.libs << 'test'
|
14
|
+
t.pattern = 'test/**/*_test.rb'
|
15
|
+
t.verbose = false
|
16
|
+
end
|
17
|
+
|
18
|
+
task default: :test
|
@@ -0,0 +1,44 @@
|
|
1
|
+
Kernel.module_eval do
|
2
|
+
|
3
|
+
def all_args_to_ivars(local_binding)
|
4
|
+
local_binding.local_variables.each do |lvar|
|
5
|
+
instance_variable_set("@#{lvar}", local_binding.local_variable_get(lvar))
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def args_to_ivars(local_binding, *local_vars)
|
10
|
+
local_vars.each do |lvar|
|
11
|
+
instance_variable_set("@#{lvar}", local_binding.local_variable_get(lvar))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def all_kwargs_to_ivars(local_binding)
|
16
|
+
local_binding.local_variable_get(:kwargs).each do |name, value|
|
17
|
+
instance_variable_set "@#{name}", value
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def set_ivars(*ivars)
|
22
|
+
ivars.each do |ivar|
|
23
|
+
instance_variable_set("@#{ivar}", send("set_#{ivar}"))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def safe_call(*args, return_value: nil, &block)
|
28
|
+
block.call self, *args
|
29
|
+
rescue
|
30
|
+
return_value
|
31
|
+
end
|
32
|
+
|
33
|
+
def safe_send(method, *args, return_value: nil)
|
34
|
+
self.send method, *args
|
35
|
+
rescue
|
36
|
+
return_value
|
37
|
+
end
|
38
|
+
|
39
|
+
def raise_error(_class_name, message = nil)
|
40
|
+
Object.const_set(_class_name, Class.new(StandardError)) unless Object.const_defined?(_class_name)
|
41
|
+
raise _class_name.constantize.new message
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class Module
|
2
|
+
|
3
|
+
def include_concerns_of(*directories)
|
4
|
+
directories.map! { |dir| dir.to_s.camelcase }
|
5
|
+
|
6
|
+
directories.each do |dir|
|
7
|
+
konstants = dir.constantize.constants(false)
|
8
|
+
konstants.each { |kon| include(const_get "#{dir}::#{kon}") }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "awesome_print"
|
2
|
+
|
3
|
+
class Object
|
4
|
+
|
5
|
+
def all_methods(include_ancestors = true, grep: nil)
|
6
|
+
|
7
|
+
_introspection_methods = %i$
|
8
|
+
methods
|
9
|
+
singleton_methods
|
10
|
+
instance_methods
|
11
|
+
private_methods
|
12
|
+
public_methods
|
13
|
+
protected_methods
|
14
|
+
private_instance_methods
|
15
|
+
public_instance_methods
|
16
|
+
protected_instance_methods
|
17
|
+
$
|
18
|
+
|
19
|
+
_introspection_methods.map! do |_m|
|
20
|
+
_methods = safe_send _m, include_ancestors
|
21
|
+
_methods = grep ? _methods&.grep(grep) : _methods
|
22
|
+
{ _m => _methods }
|
23
|
+
end
|
24
|
+
|
25
|
+
ap _introspection_methods.inject &:merge
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Eitil
|
2
|
+
class ApplicationDecorator
|
3
|
+
|
4
|
+
include ActiveModel::Model
|
5
|
+
|
6
|
+
def initialize(attributes={}, **kwargs)
|
7
|
+
super attributes
|
8
|
+
all_kwargs_to_ivars binding
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.method_missing(method_name, *args, **kwargs)
|
12
|
+
if %i$ web app $.include?(method_name.to_sym)
|
13
|
+
kwargs.any? ? send(:base, *args, **kwargs) : send(:base, *args)
|
14
|
+
end
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Eitil
|
2
|
+
module ControllerDecorator
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
included do
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def decorate(dec_item, dec_method: nil, dec_class: nil, **dec_kwargs)
|
9
|
+
all_args_to_ivars binding
|
10
|
+
set_ivars :dec_class, :dec_method, :decorator
|
11
|
+
send_to_decorator
|
12
|
+
end
|
13
|
+
|
14
|
+
def send_to_decorator
|
15
|
+
@dec_kwargs.any? ? @decorator.send(@dec_method, @dec_item, @dec_kwargs)
|
16
|
+
: @decorator.send(@dec_method, @dec_item)
|
17
|
+
|
18
|
+
rescue NoMethodError => e
|
19
|
+
inform_no_method_for_decorator_error
|
20
|
+
@dec_item
|
21
|
+
end
|
22
|
+
|
23
|
+
def inform_no_method_for_decorator_error
|
24
|
+
message = "Warning: NoMethodError for #{@dec_class}.#{@dec_method}, returned @dec_item instead."
|
25
|
+
Logger.new("#{Rails.root}/log/decorator_log.log").warn message
|
26
|
+
warn message
|
27
|
+
end
|
28
|
+
|
29
|
+
def set_dec_method
|
30
|
+
@dec_method = @dec_method || derived_dec_method || :base
|
31
|
+
end
|
32
|
+
|
33
|
+
def derived_dec_method
|
34
|
+
return unless respond_to? :params
|
35
|
+
return :app if params["isMobile"]
|
36
|
+
return :web if params["isWeb"]
|
37
|
+
end
|
38
|
+
|
39
|
+
def set_dec_class
|
40
|
+
@dec_class = @dec_class ? manual_set_dec_class : derived_dec_class
|
41
|
+
end
|
42
|
+
|
43
|
+
def manual_set_dec_class
|
44
|
+
"#{@dec_class}Decorator".constantize
|
45
|
+
end
|
46
|
+
|
47
|
+
def derived_dec_class
|
48
|
+
"#{@dec_item.class.name}Decorator".constantize
|
49
|
+
end
|
50
|
+
|
51
|
+
def set_decorator
|
52
|
+
@decorator = @dec_class.new controller_ivars
|
53
|
+
end
|
54
|
+
|
55
|
+
def controller_ivars
|
56
|
+
eval(Eitil.get_controller_ivars_method).map do |ivar|
|
57
|
+
{ ivar => instance_variable_get("@#{ivar.to_s}") }
|
58
|
+
end.inject &:merge
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
Kernel.module_eval do
|
2
|
+
|
3
|
+
def new_job(_method)
|
4
|
+
|
5
|
+
if instance_methods(false).include? _method
|
6
|
+
define_method "#{_method}_job" do
|
7
|
+
Eitil::SingleMethodJob.perform_later(_class: self.class.to_s, _method: _method.to_s, id: id)
|
8
|
+
end
|
9
|
+
|
10
|
+
elsif singleton_methods(false).include? _method
|
11
|
+
define_singleton_method "#{_method}_job" do
|
12
|
+
Eitil::SingleMethodJob.perform_later(_class: to_s, _method: _method.to_s)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Eitil
|
2
|
+
module ExtendedResources
|
3
|
+
|
4
|
+
RESOURCEFUL_ACTIONS = %i$ index new create show edit update destroy $
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def extended_resources(controller, **kwargs)
|
9
|
+
all_args_to_ivars binding
|
10
|
+
|
11
|
+
resources(controller, **resource_args) do
|
12
|
+
extended_routes&.each { |route| send(route).call controller }
|
13
|
+
yield if block_given?
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def resource_args
|
18
|
+
duplicate = @kwargs.dup
|
19
|
+
duplicate[:only] = resourceful_routes
|
20
|
+
duplicate
|
21
|
+
end
|
22
|
+
|
23
|
+
def resourceful_routes
|
24
|
+
@kwargs.dig(:only) - extended_routes
|
25
|
+
end
|
26
|
+
|
27
|
+
def extended_routes
|
28
|
+
@kwargs.dig(:only) - RESOURCEFUL_ACTIONS
|
29
|
+
end
|
30
|
+
|
31
|
+
def new_route(verb, _method, action, scope)
|
32
|
+
self.class.send :define_method, _method do
|
33
|
+
-> (controller) { send(verb, _method, to: "#{controller}##{action}", on: scope) }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
ActionDispatch::Routing::Mapper.__send__ :include, Eitil::ExtendedResources
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Eitil
|
2
|
+
module DefaultScopes
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
included do
|
5
|
+
|
6
|
+
SharableDateScopes = -> (column) {
|
7
|
+
eitil_scope :"#{column}_today", -> { where("#{column} = ?", Date.today) }
|
8
|
+
eitil_scope :"#{column}_past", -> { where("#{column} < ?", Date.today) }
|
9
|
+
eitil_scope :"#{column}_future", -> { where("#{column} > ?", Date.today) }
|
10
|
+
|
11
|
+
eitil_scope :"#{column}_on_date", -> (date) { where("#{column} = ?", date) }
|
12
|
+
eitil_scope :"#{column}_before_date", -> (date) { where("#{column} = ?", date) }
|
13
|
+
eitil_scope :"#{column}_after_date", -> (date) { where("#{column} = ?", date) }
|
14
|
+
|
15
|
+
eitil_scope :"#{column}_between_dates", -> (from, till) { where("#{column} >= ? and #{column} <= ?", from, till) }
|
16
|
+
|
17
|
+
eitil_scope :"#{column}_oldest_first", -> { order("#{column} ASC") }
|
18
|
+
eitil_scope :"#{column}_newest_first", -> { order("#{column} DESC") }
|
19
|
+
}
|
20
|
+
|
21
|
+
class << self
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def use_eitil_scopes
|
26
|
+
%i[boolean datetime date].each { |_type| send :"create_eitil_#{_type}_scopes" }
|
27
|
+
end
|
28
|
+
|
29
|
+
def eitil_scope(_name, _proc)
|
30
|
+
scope _name, _proc unless respond_to? _name
|
31
|
+
end
|
32
|
+
|
33
|
+
def columns_of_type(data_type)
|
34
|
+
columns_hash.select { |column,v| v.sql_type_metadata.type == data_type }
|
35
|
+
end
|
36
|
+
|
37
|
+
def create_eitil_boolean_scopes
|
38
|
+
columns_of_type(:boolean).map do |column, object|
|
39
|
+
eitil_scope :"#{column}_true", -> { where(column => true) }
|
40
|
+
eitil_scope :"#{column}_false", -> { where(column => [false, nil]) }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_eitil_datetime_scopes
|
45
|
+
columns_of_type(:datetime).map do |column, object|
|
46
|
+
SharableDateScopes.call column
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def create_eitil_date_scopes
|
51
|
+
columns_of_type(:date).map do |column, object|
|
52
|
+
SharableDateScopes.call column
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/config/routes.rb
ADDED
data/lib/eitil.rb
ADDED
data/lib/eitil/engine.rb
ADDED
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: eitil
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jurriaan Schrofer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-04-26 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.3
|
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.3
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: awesome_print
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.9.2
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.9.2
|
41
|
+
description: Description of Eitil.
|
42
|
+
email:
|
43
|
+
- jschrofer@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- MIT-LICENSE
|
49
|
+
- README.md
|
50
|
+
- Rakefile
|
51
|
+
- app/controllers/eitil/application_controller.rb
|
52
|
+
- app/jobs/eitil/application_job.rb
|
53
|
+
- app/mailers/eitil/application_mailer.rb
|
54
|
+
- app/models/eitil/application_record.rb
|
55
|
+
- config/initializers/monkeys/application_controller.rb
|
56
|
+
- config/initializers/monkeys/date_time.rb
|
57
|
+
- config/initializers/monkeys/hash.rb
|
58
|
+
- config/initializers/monkeys/kernel.rb
|
59
|
+
- config/initializers/monkeys/module.rb
|
60
|
+
- config/initializers/monkeys/object.rb
|
61
|
+
- config/initializers/wrappers/decorators/application_decorator.rb
|
62
|
+
- config/initializers/wrappers/decorators/controller_decorator.rb
|
63
|
+
- config/initializers/wrappers/jobs/active_job_macros.rb
|
64
|
+
- config/initializers/wrappers/jobs/single_method_job.rb
|
65
|
+
- config/initializers/wrappers/routes/extended_resources.rb
|
66
|
+
- config/initializers/wrappers/scopes/default_scopes.rb
|
67
|
+
- config/routes.rb
|
68
|
+
- lib/eitil.rb
|
69
|
+
- lib/eitil/engine.rb
|
70
|
+
- lib/eitil/version.rb
|
71
|
+
- lib/tasks/eitil_tasks.rake
|
72
|
+
homepage: https://eitje.app
|
73
|
+
licenses:
|
74
|
+
- MIT
|
75
|
+
metadata:
|
76
|
+
homepage_uri: https://eitje.app
|
77
|
+
source_code_uri: https://eitje.app
|
78
|
+
changelog_uri: https://eitje.app
|
79
|
+
post_install_message:
|
80
|
+
rdoc_options: []
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
requirements: []
|
94
|
+
rubygems_version: 3.1.2
|
95
|
+
signing_key:
|
96
|
+
specification_version: 4
|
97
|
+
summary: Summary of Eitil.
|
98
|
+
test_files: []
|