auxiliary_rails 0.3.1 → 0.4.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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +10 -1
  3. data/.rubocop_todo.yml +1 -7
  4. data/.ruby-version +1 -1
  5. data/CHANGELOG.md +11 -1
  6. data/CODE_OF_CONDUCT.md +128 -0
  7. data/Gemfile.lock +157 -131
  8. data/README.md +76 -15
  9. data/auxiliary_rails.gemspec +10 -5
  10. data/bin/rspec +29 -0
  11. data/lib/auxiliary_rails/application/command.rb +3 -6
  12. data/lib/auxiliary_rails/application/error.rb +44 -4
  13. data/lib/auxiliary_rails/application/form.rb +1 -0
  14. data/lib/auxiliary_rails/application/query.rb +11 -7
  15. data/lib/auxiliary_rails/application/service.rb +42 -0
  16. data/lib/auxiliary_rails/concerns/callable.rb +23 -0
  17. data/lib/auxiliary_rails/concerns/errorable.rb +12 -12
  18. data/lib/auxiliary_rails/concerns/performable.rb +11 -19
  19. data/lib/auxiliary_rails/railtie.rb +2 -1
  20. data/lib/auxiliary_rails/version.rb +1 -1
  21. data/lib/auxiliary_rails/view_helpers/display_helper.rb +30 -0
  22. data/lib/auxiliary_rails/view_helpers.rb +4 -0
  23. data/lib/auxiliary_rails.rb +3 -1
  24. data/lib/generators/auxiliary_rails/install_errors_controller_generator.rb +31 -0
  25. data/lib/generators/auxiliary_rails/install_generator.rb +1 -0
  26. data/lib/generators/auxiliary_rails/service_generator.rb +48 -0
  27. data/lib/generators/auxiliary_rails/templates/commands/command_spec_template.rb +1 -1
  28. data/lib/generators/auxiliary_rails/templates/errors_controller/errors_controller_template.rb +15 -0
  29. data/lib/generators/auxiliary_rails/templates/errors_controller/not_found_template.html.erb +2 -0
  30. data/lib/generators/auxiliary_rails/templates/errors_controller/show_template.html.erb +1 -0
  31. data/lib/generators/auxiliary_rails/templates/errors_controller/unacceptable_template.html.erb +2 -0
  32. data/lib/generators/auxiliary_rails/templates/services/service_spec_template.rb +5 -0
  33. data/lib/generators/auxiliary_rails/templates/services/service_template.rb +10 -0
  34. 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://en.wikipedia.org/wiki/Command_pattern).
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
- # using `attr_reader` and set it as a regular instance var inside the command
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 @user.persistent?
129
+ error! unless user.persistent?
107
130
 
108
- send_notification
131
+ send_notifications
109
132
  # ...
110
133
  end
111
134
 
112
- # Always end the `#perform` method with `success!`
113
- # this will set the proper status and allow to chain command methods.
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
- @user = User.create(email: email, password: password)
143
+ User.create(email: email, password: password)
121
144
  end
122
145
 
123
- def send_notification
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/inmate.rb
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
@@ -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 = 'AuxiliaryRails provides extra layers and utils ' \
12
- 'for helping to build solid and clean Ruby on Rails applications'
13
- spec.description = <<~DESC
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', '~> 0.80'
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', '< 7'
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
- # Initializes command with <tt>args</tt> and runs <tt>#call</tt> method.
32
- #
33
- # @return [self]
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
- class Error < StandardError
4
- # @return [self] Creates new error object
5
- def self.wrap(error)
6
- new(error.message)
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,4 +1,5 @@
1
1
  require 'active_model'
2
+ require 'auxiliary_rails/concerns/performable'
2
3
 
3
4
  module AuxiliaryRails
4
5
  module Application
@@ -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 { nil }
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 Metrics/AbcSize, Style/GuardClause
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 Metrics/AbcSize, Style/GuardClause
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
- # extend ActiveSupport::Concern
4
+ extend ActiveSupport::Concern
5
5
 
6
- def error!(message = nil)
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
- AuxiliaryRails::Application::Error
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 [Symol] Desired command status
62
- # @param &_block Code to be executed if status matches
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, &_block)
65
- ensure_execution!
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.send :include, ViewHelpers
7
+ ActionView::Base.include ViewHelpers
7
8
  end
8
9
  end
9
10
  end
@@ -1,3 +1,3 @@
1
1
  module AuxiliaryRails
2
- VERSION = '0.3.1'.freeze
2
+ VERSION = '0.4.0'.freeze
3
3
  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
@@ -1,5 +1,9 @@
1
+ require 'auxiliary_rails/view_helpers/display_helper'
2
+
1
3
  module AuxiliaryRails
2
4
  module ViewHelpers
5
+ include DisplayHelper
6
+
3
7
  def current_controller?(*ctrl_names)
4
8
  ctrl_names.include?(params[:controller])
5
9
  end
@@ -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
@@ -5,6 +5,7 @@ module AuxiliaryRails
5
5
  def install
6
6
  generate 'auxiliary_rails:install_commands'
7
7
  generate 'auxiliary_rails:install_errors'
8
+ generate 'auxiliary_rails:install_errors_controller'
8
9
  end
9
10
  end
10
11
  end