auxiliary_rails 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +10 -1
- data/.rubocop_todo.yml +1 -7
- data/.ruby-version +1 -1
- data/CHANGELOG.md +11 -1
- data/CODE_OF_CONDUCT.md +128 -0
- data/Gemfile.lock +157 -131
- data/README.md +76 -15
- data/auxiliary_rails.gemspec +10 -5
- data/bin/rspec +29 -0
- data/lib/auxiliary_rails/application/command.rb +3 -6
- data/lib/auxiliary_rails/application/error.rb +44 -4
- data/lib/auxiliary_rails/application/form.rb +1 -0
- data/lib/auxiliary_rails/application/query.rb +11 -7
- data/lib/auxiliary_rails/application/service.rb +42 -0
- data/lib/auxiliary_rails/concerns/callable.rb +23 -0
- data/lib/auxiliary_rails/concerns/errorable.rb +12 -12
- data/lib/auxiliary_rails/concerns/performable.rb +11 -19
- data/lib/auxiliary_rails/railtie.rb +2 -1
- data/lib/auxiliary_rails/version.rb +1 -1
- data/lib/auxiliary_rails/view_helpers/display_helper.rb +30 -0
- data/lib/auxiliary_rails/view_helpers.rb +4 -0
- data/lib/auxiliary_rails.rb +3 -1
- data/lib/generators/auxiliary_rails/install_errors_controller_generator.rb +31 -0
- data/lib/generators/auxiliary_rails/install_generator.rb +1 -0
- data/lib/generators/auxiliary_rails/service_generator.rb +48 -0
- data/lib/generators/auxiliary_rails/templates/commands/command_spec_template.rb +1 -1
- data/lib/generators/auxiliary_rails/templates/errors_controller/errors_controller_template.rb +15 -0
- data/lib/generators/auxiliary_rails/templates/errors_controller/not_found_template.html.erb +2 -0
- data/lib/generators/auxiliary_rails/templates/errors_controller/show_template.html.erb +1 -0
- data/lib/generators/auxiliary_rails/templates/errors_controller/unacceptable_template.html.erb +2 -0
- data/lib/generators/auxiliary_rails/templates/services/service_spec_template.rb +5 -0
- data/lib/generators/auxiliary_rails/templates/services/service_template.rb +10 -0
- metadata +38 -17
data/README.md
CHANGED
@@ -11,12 +11,15 @@ Collection of classes, configs, scripts, generators for Ruby on Rails helping yo
|
|
11
11
|
Add one of these lines to your application's `Gemfile`:
|
12
12
|
|
13
13
|
```ruby
|
14
|
-
# version released to RubyGems
|
14
|
+
# version released to RubyGems (recommended)
|
15
15
|
gem 'auxiliary_rails'
|
16
|
+
|
16
17
|
# or latest version from the repository
|
17
18
|
gem 'auxiliary_rails', git: 'https://github.com/ergoserv/auxiliary_rails'
|
18
|
-
# or from a specific branch of the repository
|
19
|
+
# or from a specific branch of the GitHub repository
|
19
20
|
gem 'auxiliary_rails', github: 'ergoserv/auxiliary_rails', branch: 'develop'
|
21
|
+
# or from a local path (for development and testing purposes)
|
22
|
+
gem 'auxiliary_rails', path: '../auxiliary_rails'
|
20
23
|
```
|
21
24
|
|
22
25
|
And then execute:
|
@@ -56,17 +59,35 @@ rails generate auxiliary_rails:install
|
|
56
59
|
# Install one by one
|
57
60
|
rails generate auxiliary_rails:install_commands
|
58
61
|
rails generate auxiliary_rails:install_errors
|
62
|
+
rails generate auxiliary_rails:install_errors_controller
|
59
63
|
|
60
64
|
# API resource generator
|
61
65
|
rails generate auxiliary_rails:api_resource
|
62
66
|
|
63
67
|
# Command generator
|
64
68
|
rails generate auxiliary_rails:command
|
69
|
+
|
70
|
+
# Service generator
|
71
|
+
rails generate auxiliary_rails:service
|
72
|
+
```
|
73
|
+
|
74
|
+
### API Resources
|
75
|
+
|
76
|
+
Read article [Building an API](https://github.com/ergoserv/handbook/blob/master/guides/building_api.md) for more details.
|
77
|
+
|
78
|
+
Use generator to generate appropriate classes and files (Resource, Entity, Helper, Spec) for the specified end-point:
|
79
|
+
|
80
|
+
```sh
|
81
|
+
rails generate auxiliary_rails:api_resource
|
65
82
|
```
|
66
83
|
|
84
|
+
## Application
|
85
|
+
|
67
86
|
### Command Objects
|
68
87
|
|
69
|
-
Variation of implementation of [Command pattern](https://
|
88
|
+
Variation of implementation of [Command pattern](https://refactoring.guru/design-patterns/command).
|
89
|
+
|
90
|
+
Read post [Command Objects - a.k.a Service Objects in Ruby on Rails - The Ergonomic Way](https://www.ergoserv.com/blog/command-objects-aka-service-objects-in-ruby-on-rails-the-ergonomic-way) for more details.
|
70
91
|
|
71
92
|
```ruby
|
72
93
|
# app/commands/application_command.rb
|
@@ -81,8 +102,8 @@ class RegisterUserCommand < ApplicationCommand
|
|
81
102
|
param :email
|
82
103
|
param :password
|
83
104
|
|
84
|
-
# Define the results of the command
|
85
|
-
#
|
105
|
+
# Define the results of the command using `attr_reader`
|
106
|
+
# and set it as a regular instance var inside the command
|
86
107
|
attr_reader :user
|
87
108
|
|
88
109
|
# Regular Active Model Validations can be used to validate params
|
@@ -90,9 +111,11 @@ class RegisterUserCommand < ApplicationCommand
|
|
90
111
|
# Use #valid?, #invalid?, #validate! methods to engage validations
|
91
112
|
validates :password, length: { in: 8..32 }
|
92
113
|
|
93
|
-
# Define the only public method `#perform`
|
94
|
-
# where command's flow is defined
|
114
|
+
# Define the only public method `#perform` where command's flow is defined
|
95
115
|
def perform
|
116
|
+
# Use `return failure!` and `return success!` inside `#perform` method
|
117
|
+
# to control exits from the command with appropriate status.
|
118
|
+
|
96
119
|
# Use `return failure!` to exit from the command with failure
|
97
120
|
return failure! if registration_disabled?
|
98
121
|
|
@@ -100,27 +123,27 @@ class RegisterUserCommand < ApplicationCommand
|
|
100
123
|
transaction do
|
101
124
|
# Keep the `#perform` method short and clean, put all the steps, actions
|
102
125
|
# and business logic into meaningful and self-explanatory methods
|
103
|
-
create_user
|
126
|
+
@user = create_user
|
104
127
|
|
105
128
|
# Use `error!` method to interrupt the flow raising an error
|
106
|
-
error! unless
|
129
|
+
error! unless user.persistent?
|
107
130
|
|
108
|
-
|
131
|
+
send_notifications
|
109
132
|
# ...
|
110
133
|
end
|
111
134
|
|
112
|
-
# Always end the `#perform` method with `success
|
113
|
-
#
|
135
|
+
# Always end the `#perform` method with `success!`.
|
136
|
+
# It will set the proper command's execution status.
|
114
137
|
success!
|
115
138
|
end
|
116
139
|
|
117
140
|
private
|
118
141
|
|
119
142
|
def create_user
|
120
|
-
|
143
|
+
User.create(email: email, password: password)
|
121
144
|
end
|
122
145
|
|
123
|
-
def
|
146
|
+
def send_notifications
|
124
147
|
# ...
|
125
148
|
end
|
126
149
|
end
|
@@ -150,6 +173,17 @@ class RegistrationsController
|
|
150
173
|
end
|
151
174
|
```
|
152
175
|
|
176
|
+
### Error Objects
|
177
|
+
|
178
|
+
Custom error objects.
|
179
|
+
Read article [Error Handling](https://github.com/ergoserv/handbook/blob/master/guides/error_handling.md) for more details.
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
# app/errors/application_error.rb
|
183
|
+
class ApplicationCommand < AuxiliaryRails::Application::Error
|
184
|
+
end
|
185
|
+
```
|
186
|
+
|
153
187
|
### Form Objects
|
154
188
|
|
155
189
|
```ruby
|
@@ -252,7 +286,7 @@ end
|
|
252
286
|
### Usage ###
|
253
287
|
|
254
288
|
# it is possible to wrap query object in a scope and use as a regular scope
|
255
|
-
# app/models/
|
289
|
+
# app/models/author.rb
|
256
290
|
class Author < ApplicationRecord
|
257
291
|
scope :name_like, ->(value) { AuthorsQuery.call(name_like: value) }
|
258
292
|
end
|
@@ -263,11 +297,38 @@ authors = Author.name_like('Arthur')
|
|
263
297
|
authors = AuthorsWithBooksQuery.call(min_book_count: 10)
|
264
298
|
```
|
265
299
|
|
300
|
+
### Service Modules
|
301
|
+
|
302
|
+
Read [Service Modules](https://github.com/ergoserv/handbook/blob/master/guides/service_modules.md) for more details.
|
303
|
+
|
304
|
+
**Service Generator**
|
305
|
+
|
306
|
+
```sh
|
307
|
+
rails generate auxiliary_rails:service
|
308
|
+
```
|
309
|
+
|
310
|
+
**Service Config** - provides a unified access to a service configs and loads the first found from:
|
311
|
+
|
312
|
+
- Constant (`MyService::CONFIG`)
|
313
|
+
- Application config file (`config/settings.yml`, see gem [`config`](https://github.com/rubyconfig/config))
|
314
|
+
- Service config file (`config/services/my_service.yml`)
|
315
|
+
|
316
|
+
```ruby
|
317
|
+
# app/services/my_service.rb
|
318
|
+
module MyService
|
319
|
+
extend AuxiliaryRails::Application::Service
|
320
|
+
end
|
321
|
+
|
322
|
+
# usage
|
323
|
+
MyService.config.some_key
|
324
|
+
```
|
325
|
+
|
266
326
|
### View Helpers
|
267
327
|
|
268
328
|
```ruby
|
269
329
|
current_controller?(*ctrl_names)
|
270
330
|
current_action?(*action_names)
|
331
|
+
display_name(resource)
|
271
332
|
```
|
272
333
|
|
273
334
|
## Development
|
data/auxiliary_rails.gemspec
CHANGED
@@ -8,9 +8,11 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.authors = ['Dmitry Babenko', 'ErgoServ']
|
9
9
|
spec.email = ['dmitry@ergoserv.com', 'hello@ergoserv.com']
|
10
10
|
|
11
|
-
spec.summary
|
12
|
-
|
13
|
-
|
11
|
+
spec.summary = <<~DESC
|
12
|
+
AuxiliaryRails provides extra layers and utils
|
13
|
+
for helping to build solid and clean Ruby on Rails applications
|
14
|
+
DESC
|
15
|
+
spec.description = <<~DESC
|
14
16
|
AuxiliaryRails is a collection of classes, configs, scripts,
|
15
17
|
generators for Ruby on Rails helping you get things done, better.
|
16
18
|
DESC
|
@@ -31,17 +33,20 @@ Gem::Specification.new do |spec|
|
|
31
33
|
spec.executables = ['auxiliary_rails']
|
32
34
|
spec.require_paths = ['lib']
|
33
35
|
|
36
|
+
spec.required_ruby_version = '>= 2.5'
|
37
|
+
|
34
38
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
35
39
|
spec.add_development_dependency 'pry'
|
36
40
|
spec.add_development_dependency 'rake'
|
37
41
|
spec.add_development_dependency 'rspec', '~> 3.8'
|
38
|
-
spec.add_development_dependency 'rubocop', '
|
42
|
+
spec.add_development_dependency 'rubocop', '1.20.0'
|
39
43
|
spec.add_development_dependency 'rubocop-performance'
|
44
|
+
spec.add_development_dependency 'rubocop-rake'
|
40
45
|
spec.add_development_dependency 'rubocop-rspec'
|
41
46
|
|
42
47
|
spec.add_runtime_dependency 'dry-core'
|
43
48
|
spec.add_runtime_dependency 'dry-initializer'
|
44
49
|
spec.add_runtime_dependency 'dry-initializer-rails'
|
45
|
-
spec.add_runtime_dependency 'rails', '>= 5.2'
|
50
|
+
spec.add_runtime_dependency 'rails', '>= 5.2'
|
46
51
|
spec.add_runtime_dependency 'thor'
|
47
52
|
end
|
data/bin/rspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'rspec' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require "pathname"
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path("../bundle", __FILE__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require "rubygems"
|
27
|
+
require "bundler/setup"
|
28
|
+
|
29
|
+
load Gem.bin_path("rspec-core", "rspec")
|
@@ -28,12 +28,9 @@ module AuxiliaryRails
|
|
28
28
|
# @param name [Symbol]
|
29
29
|
# @param options [Hash]
|
30
30
|
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
def call(*args)
|
35
|
-
new(*args).call
|
36
|
-
end
|
31
|
+
# @!method call(*args, **kws)
|
32
|
+
# @see AuxiliaryRails::Corcerns::Callable
|
33
|
+
# @return [self]
|
37
34
|
|
38
35
|
# Defines `scope` for <tt>ActiveModel::Translation</tt>
|
39
36
|
#
|
@@ -1,10 +1,50 @@
|
|
1
1
|
module AuxiliaryRails
|
2
2
|
module Application
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
# @abstract
|
4
|
+
class Error < RuntimeError
|
5
|
+
attr_accessor :context
|
6
|
+
attr_reader :exception, :severity
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def i18n_scope
|
10
|
+
"errors.#{name.underscore}"
|
11
|
+
end
|
12
|
+
|
13
|
+
# @return [self] Wraps exception into a new Application Error object
|
14
|
+
def wrap(exception, context: {}, severity: nil)
|
15
|
+
new(exception.message, context: context, exception: exception, severity: severity)
|
16
|
+
end
|
7
17
|
end
|
18
|
+
|
19
|
+
def initialize(message = nil, context: {}, exception: nil, severity: nil)
|
20
|
+
super message
|
21
|
+
|
22
|
+
self.context = default_context.merge(context || {})
|
23
|
+
self.exception = exception
|
24
|
+
self.severity = severity&.to_sym || default_severity
|
25
|
+
end
|
26
|
+
|
27
|
+
def default_context
|
28
|
+
{}
|
29
|
+
end
|
30
|
+
|
31
|
+
def default_severity
|
32
|
+
:error
|
33
|
+
end
|
34
|
+
|
35
|
+
def friendly_message
|
36
|
+
I18n.t(:default,
|
37
|
+
scope: self.class.i18n_scope,
|
38
|
+
default: 'We are sorry, but something went wrong.')
|
39
|
+
end
|
40
|
+
|
41
|
+
def report
|
42
|
+
raise NotImplementedError
|
43
|
+
end
|
44
|
+
|
45
|
+
protected
|
46
|
+
|
47
|
+
attr_writer :exception, :severity
|
8
48
|
end
|
9
49
|
end
|
10
50
|
end
|
@@ -1,30 +1,34 @@
|
|
1
|
+
require 'auxiliary_rails/concerns/callable'
|
1
2
|
require 'auxiliary_rails/concerns/errorable'
|
2
3
|
require 'dry/core/class_attributes'
|
3
4
|
require 'dry-initializer'
|
4
5
|
|
5
6
|
module AuxiliaryRails
|
6
7
|
module Application
|
8
|
+
# @abstract
|
7
9
|
class Query
|
8
10
|
extend Dry::Core::ClassAttributes
|
9
11
|
extend Dry::Initializer
|
12
|
+
include AuxiliaryRails::Concerns::Callable
|
10
13
|
include AuxiliaryRails::Concerns::Errorable
|
11
14
|
|
12
15
|
defines :default_relation
|
13
16
|
|
14
|
-
option :relation, default: proc {
|
15
|
-
|
16
|
-
def self.call(*args)
|
17
|
-
new(*args).call
|
18
|
-
end
|
17
|
+
option :relation, default: proc {}
|
19
18
|
|
20
19
|
def call
|
21
20
|
ensure_proper_relation_types!
|
22
21
|
|
23
22
|
perform
|
24
23
|
|
24
|
+
if !queriable_object?(query)
|
25
|
+
error!('Invalid class of resulted query')
|
26
|
+
end
|
27
|
+
|
25
28
|
query
|
26
29
|
end
|
27
30
|
|
31
|
+
# @abstract
|
28
32
|
def perform
|
29
33
|
raise NotImplementedError
|
30
34
|
end
|
@@ -41,7 +45,7 @@ module AuxiliaryRails
|
|
41
45
|
|
42
46
|
private
|
43
47
|
|
44
|
-
# rubocop:disable
|
48
|
+
# rubocop:disable Style/GuardClause
|
45
49
|
def ensure_proper_relation_types!
|
46
50
|
if self.class.default_relation.nil?
|
47
51
|
error!('Undefined `default_relation`')
|
@@ -53,7 +57,7 @@ module AuxiliaryRails
|
|
53
57
|
error!('Invalid class of `relation` option')
|
54
58
|
end
|
55
59
|
end
|
56
|
-
# rubocop:enable
|
60
|
+
# rubocop:enable Style/GuardClause
|
57
61
|
|
58
62
|
def queriable_object?(object)
|
59
63
|
object.is_a?(ActiveRecord::Relation)
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'active_support/ordered_options'
|
3
|
+
|
4
|
+
module AuxiliaryRails
|
5
|
+
module Application
|
6
|
+
module Service
|
7
|
+
def self.included(klass)
|
8
|
+
raise AuxiliaryRails::Error,
|
9
|
+
"Use `extend` insted of `include` for #{self} in #{klass}"
|
10
|
+
end
|
11
|
+
|
12
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
13
|
+
def config
|
14
|
+
return @config if @config.present?
|
15
|
+
|
16
|
+
# load from constant
|
17
|
+
if const_defined?(:CONFIG)
|
18
|
+
return @config = ActiveSupport::OrderedOptions.new.update(const_get(:CONFIG))
|
19
|
+
end
|
20
|
+
|
21
|
+
service_name = name.underscore
|
22
|
+
|
23
|
+
# load from service config file
|
24
|
+
if Rails.root.join("config/services/#{service_name}.yml").exist?
|
25
|
+
return @config = Rails.application.config_for("services/#{service_name}")
|
26
|
+
end
|
27
|
+
|
28
|
+
# load from application config
|
29
|
+
if Object.const_defined?(:Config) && Config.respond_to?(:const_name)
|
30
|
+
app_config = Object.const_get(Config.const_name)
|
31
|
+
if app_config.dig(:services, service_name).present?
|
32
|
+
return @config = app_config[:services][service_name]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
raise AuxiliaryRails::Error,
|
37
|
+
"Unable to find suitable config for #{name} module"
|
38
|
+
end
|
39
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module AuxiliaryRails
|
2
|
+
module Concerns
|
3
|
+
module Callable
|
4
|
+
def self.included(klass)
|
5
|
+
klass.extend(ClassMethods)
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
# Initializes object and runs <tt>#call</tt> method.
|
10
|
+
#
|
11
|
+
# @return [self]
|
12
|
+
def call(*args, **kws)
|
13
|
+
new(*args, **kws).call
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# @abstract
|
18
|
+
def call
|
19
|
+
raise NotImplementedError
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,22 +1,22 @@
|
|
1
1
|
module AuxiliaryRails
|
2
2
|
module Concerns
|
3
3
|
module Errorable
|
4
|
-
|
4
|
+
extend ActiveSupport::Concern
|
5
5
|
|
6
|
-
|
7
|
-
message ||= "`#{self.class}` raised error."
|
8
|
-
raise error_class, message
|
9
|
-
end
|
10
|
-
|
11
|
-
if defined?(ApplicationError)
|
12
|
-
def error_class
|
13
|
-
ApplicationError
|
14
|
-
end
|
15
|
-
else
|
6
|
+
class_methods do
|
16
7
|
def error_class
|
17
|
-
|
8
|
+
if Object.const_defined?(:ApplicationError)
|
9
|
+
ApplicationError
|
10
|
+
else
|
11
|
+
AuxiliaryRails::Application::Error
|
12
|
+
end
|
18
13
|
end
|
19
14
|
end
|
15
|
+
|
16
|
+
def error!(message = nil)
|
17
|
+
message ||= "`#{self.class}` raised error."
|
18
|
+
raise self.class.error_class, message
|
19
|
+
end
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'active_support/concern'
|
2
|
+
require 'auxiliary_rails/concerns/callable'
|
2
3
|
require 'auxiliary_rails/concerns/errorable'
|
3
4
|
|
4
5
|
module AuxiliaryRails
|
@@ -6,14 +7,9 @@ module AuxiliaryRails
|
|
6
7
|
module Performable
|
7
8
|
extend ActiveSupport::Concern
|
8
9
|
include ActiveModel::Validations
|
10
|
+
include AuxiliaryRails::Concerns::Callable
|
9
11
|
include AuxiliaryRails::Concerns::Errorable
|
10
12
|
|
11
|
-
class_methods do
|
12
|
-
def call(*args)
|
13
|
-
new(*args).call
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
13
|
def call(options = {})
|
18
14
|
ensure_empty_status!
|
19
15
|
|
@@ -58,24 +54,15 @@ module AuxiliaryRails
|
|
58
54
|
# Provides ability to execude block of the code depending on
|
59
55
|
# command execution status
|
60
56
|
#
|
61
|
-
# @param status [
|
62
|
-
# @param &
|
57
|
+
# @param status [Symbol] Desired command status
|
58
|
+
# @param &block Code to be executed if status matches
|
63
59
|
# @return [self]
|
64
|
-
def on(status, &
|
65
|
-
|
66
|
-
|
67
|
-
return self unless status?(status)
|
68
|
-
|
69
|
-
yield(self) if block_given?
|
60
|
+
def on(status, &block)
|
61
|
+
yield(self) if status?(status) && block
|
70
62
|
|
71
63
|
self
|
72
64
|
end
|
73
65
|
|
74
|
-
# Shortcut for <tt>ActiveRecord::Base.transaction</tt>
|
75
|
-
def transaction(&block)
|
76
|
-
ActiveRecord::Base.transaction(&block) if block_given?
|
77
|
-
end
|
78
|
-
|
79
66
|
protected
|
80
67
|
|
81
68
|
attr_accessor :performable_status
|
@@ -123,6 +110,11 @@ module AuxiliaryRails
|
|
123
110
|
self.performable_status = :success
|
124
111
|
self
|
125
112
|
end
|
113
|
+
|
114
|
+
# Shortcut for <tt>ActiveRecord::Base.transaction</tt>
|
115
|
+
def transaction(&block)
|
116
|
+
ActiveRecord::Base.transaction(&block) if block
|
117
|
+
end
|
126
118
|
end
|
127
119
|
end
|
128
120
|
end
|
@@ -1,9 +1,10 @@
|
|
1
|
+
require 'rails/railtie'
|
1
2
|
require 'auxiliary_rails/view_helpers'
|
2
3
|
|
3
4
|
module AuxiliaryRails
|
4
5
|
class Railtie < Rails::Railtie
|
5
6
|
initializer 'auxiliary_rails.view_helpers' do
|
6
|
-
ActionView::Base.
|
7
|
+
ActionView::Base.include ViewHelpers
|
7
8
|
end
|
8
9
|
end
|
9
10
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module AuxiliaryRails
|
2
|
+
module ViewHelpers
|
3
|
+
module DisplayHelper
|
4
|
+
DISPLAY_NAME_METHODS = %i[
|
5
|
+
display_name
|
6
|
+
name
|
7
|
+
title
|
8
|
+
full_name
|
9
|
+
username
|
10
|
+
email
|
11
|
+
].freeze
|
12
|
+
|
13
|
+
def display_name(resource)
|
14
|
+
return if resource.nil?
|
15
|
+
|
16
|
+
DISPLAY_NAME_METHODS.each do |method_name|
|
17
|
+
if resource.respond_to?(method_name)
|
18
|
+
return resource.public_send(method_name)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
if resource.respond_to?(:model_name) && resource.respond_to?(:id)
|
23
|
+
return "#{resource.model_name.human} ##{resource.id}"
|
24
|
+
end
|
25
|
+
|
26
|
+
resource.to_s
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/auxiliary_rails.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
require 'auxiliary_rails/application/command'
|
2
|
-
require 'auxiliary_rails/application/form'
|
3
2
|
require 'auxiliary_rails/application/error'
|
3
|
+
require 'auxiliary_rails/application/form'
|
4
|
+
require 'auxiliary_rails/application/service'
|
4
5
|
require 'auxiliary_rails/application/query'
|
6
|
+
|
5
7
|
require 'auxiliary_rails/railtie'
|
6
8
|
require 'auxiliary_rails/version'
|
7
9
|
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rails'
|
2
|
+
|
3
|
+
module AuxiliaryRails
|
4
|
+
class InstallErrorsControllerGenerator < ::Rails::Generators::Base
|
5
|
+
source_root File.expand_path('templates/errors_controller', __dir__)
|
6
|
+
|
7
|
+
VIEW_TEMPLATES = %w[show not_found unacceptable].freeze
|
8
|
+
|
9
|
+
def copy_controller_file
|
10
|
+
copy_file 'errors_controller_template.rb',
|
11
|
+
'app/controllers/errors_controller.rb'
|
12
|
+
end
|
13
|
+
|
14
|
+
def copy_view_files
|
15
|
+
VIEW_TEMPLATES.each do |tempate_name|
|
16
|
+
copy_file "#{tempate_name}_template.html.erb",
|
17
|
+
"app/views/errors/#{tempate_name}.html.erb"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def add_route
|
22
|
+
route "match '/404', to: 'errors#not_found', via: :all"
|
23
|
+
route "match '/422', to: 'errors#unacceptable', via: :all"
|
24
|
+
route "match '/500', to: 'errors#show', via: :all"
|
25
|
+
end
|
26
|
+
|
27
|
+
def add_exceptions_app_config
|
28
|
+
application 'config.exceptions_app = routes'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|