auxiliary_rails 0.2.0 → 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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitlab-ci.yml +26 -0
  3. data/.rubocop.yml +31 -3
  4. data/.rubocop_todo.yml +3 -19
  5. data/.ruby-version +1 -1
  6. data/.yardopts +5 -0
  7. data/CHANGELOG.md +39 -2
  8. data/CODE_OF_CONDUCT.md +128 -0
  9. data/CONTRIBUTING.md +0 -6
  10. data/Gemfile.lock +164 -132
  11. data/README.md +267 -5
  12. data/auxiliary_rails.gemspec +18 -13
  13. data/bin/rspec +29 -0
  14. data/bin/rubocop +29 -0
  15. data/bitbucket-pipelines.yml +35 -0
  16. data/lib/auxiliary_rails/application/command.rb +53 -0
  17. data/lib/auxiliary_rails/application/error.rb +50 -0
  18. data/lib/auxiliary_rails/application/form.rb +31 -0
  19. data/lib/auxiliary_rails/application/query.rb +75 -0
  20. data/lib/auxiliary_rails/application/service.rb +42 -0
  21. data/lib/auxiliary_rails/cli.rb +18 -5
  22. data/lib/auxiliary_rails/concerns/callable.rb +23 -0
  23. data/lib/auxiliary_rails/concerns/errorable.rb +22 -0
  24. data/lib/auxiliary_rails/concerns/performable.rb +120 -0
  25. data/lib/auxiliary_rails/railtie.rb +2 -1
  26. data/lib/auxiliary_rails/version.rb +1 -1
  27. data/lib/auxiliary_rails/view_helpers/display_helper.rb +30 -0
  28. data/lib/auxiliary_rails/view_helpers.rb +4 -0
  29. data/lib/auxiliary_rails.rb +7 -3
  30. data/lib/generators/auxiliary_rails/command_generator.rb +1 -1
  31. data/lib/generators/auxiliary_rails/install_commands_generator.rb +5 -0
  32. data/lib/generators/auxiliary_rails/install_errors_controller_generator.rb +31 -0
  33. data/lib/generators/auxiliary_rails/install_generator.rb +1 -1
  34. data/lib/generators/auxiliary_rails/service_generator.rb +48 -0
  35. data/lib/generators/auxiliary_rails/templates/application_error_template.rb +1 -1
  36. data/lib/generators/auxiliary_rails/templates/commands/application_command_template.rb +1 -1
  37. data/lib/generators/auxiliary_rails/templates/commands/command_spec_template.rb +1 -1
  38. data/lib/generators/auxiliary_rails/templates/commands/command_template.rb +2 -2
  39. data/lib/generators/auxiliary_rails/templates/commands/commands.en_template.yml +5 -0
  40. data/lib/generators/auxiliary_rails/templates/errors_controller/errors_controller_template.rb +15 -0
  41. data/lib/generators/auxiliary_rails/templates/errors_controller/not_found_template.html.erb +2 -0
  42. data/lib/generators/auxiliary_rails/templates/errors_controller/show_template.html.erb +1 -0
  43. data/lib/generators/auxiliary_rails/templates/errors_controller/unacceptable_template.html.erb +2 -0
  44. data/lib/generators/auxiliary_rails/templates/services/service_spec_template.rb +5 -0
  45. data/lib/generators/auxiliary_rails/templates/services/service_template.rb +10 -0
  46. data/templates/rails/elementary.rb +39 -10
  47. metadata +87 -32
  48. data/lib/auxiliary_rails/abstract_command.rb +0 -95
  49. data/lib/auxiliary_rails/abstract_error.rb +0 -7
  50. data/lib/generators/auxiliary_rails/install_rubocop_generator.rb +0 -29
  51. data/lib/generators/auxiliary_rails/templates/rubocop/rubocop_auxiliary_rails_template.yml +0 -65
  52. data/lib/generators/auxiliary_rails/templates/rubocop/rubocop_template.yml +0 -11
@@ -8,24 +8,24 @@ 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
17
19
  spec.homepage = 'https://github.com/ergoserv/auxiliary_rails'
18
20
  spec.license = 'MIT'
19
21
 
20
- if spec.respond_to?(:metadata)
21
- spec.metadata['homepage_uri'] = 'https://github.com/ergoserv/auxiliary_rails'
22
- spec.metadata['source_code_uri'] = 'https://github.com/ergoserv/auxiliary_rails'
23
- spec.metadata['changelog_uri'] = 'https://github.com/ergoserv/auxiliary_rails/blob/master/CHANGELOG.md'
24
- else
25
- raise 'RubyGems 2.0 or newer is required'
26
- end
22
+ raise 'RubyGems 2.0 or newer is required' unless spec.respond_to?(:metadata)
27
23
 
28
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
24
+ spec.metadata['homepage_uri'] = spec.homepage
25
+ spec.metadata['source_code_uri'] = spec.homepage
26
+ spec.metadata['changelog_uri'] = "#{spec.homepage}/releases"
27
+
28
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
29
29
  `git ls-files -z`.split("\x0").reject do |f|
30
30
  f.match(%r{^(test|spec|features)/})
31
31
  end
@@ -33,15 +33,20 @@ Gem::Specification.new do |spec|
33
33
  spec.executables = ['auxiliary_rails']
34
34
  spec.require_paths = ['lib']
35
35
 
36
+ spec.required_ruby_version = '>= 2.5'
37
+
36
38
  spec.add_development_dependency 'bundler', '~> 2.0'
37
39
  spec.add_development_dependency 'pry'
38
- spec.add_development_dependency 'rails', '>= 5.2', '< 7'
39
40
  spec.add_development_dependency 'rake'
40
41
  spec.add_development_dependency 'rspec', '~> 3.8'
41
- spec.add_development_dependency 'rubocop'
42
+ spec.add_development_dependency 'rubocop', '1.20.0'
42
43
  spec.add_development_dependency 'rubocop-performance'
44
+ spec.add_development_dependency 'rubocop-rake'
43
45
  spec.add_development_dependency 'rubocop-rspec'
44
46
 
47
+ spec.add_runtime_dependency 'dry-core'
48
+ spec.add_runtime_dependency 'dry-initializer'
45
49
  spec.add_runtime_dependency 'dry-initializer-rails'
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")
data/bin/rubocop 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 'rubocop' 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("rubocop", "rubocop")
@@ -0,0 +1,35 @@
1
+ image: ruby:2.6.5
2
+
3
+ definitions:
4
+ caches:
5
+ bundler: vendor/bundle
6
+
7
+ pipelines:
8
+ default:
9
+ - step:
10
+ name: Build
11
+ caches:
12
+ - bundler
13
+ script:
14
+ - gem install bundler
15
+ - bundle config set path vendor/bundle
16
+ - bundle install
17
+ - parallel:
18
+ - step:
19
+ name: RSpec
20
+ caches:
21
+ - bundler
22
+ script:
23
+ - gem install bundler
24
+ - bundle config set path vendor/bundle
25
+ - bundle install
26
+ - bundle exec rspec
27
+ - step:
28
+ name: RuboCop
29
+ caches:
30
+ - bundler
31
+ script:
32
+ - gem install bundler
33
+ - bundle config set path vendor/bundle
34
+ - bundle install
35
+ - bundle exec rubocop
@@ -0,0 +1,53 @@
1
+ require 'active_model'
2
+ require 'auxiliary_rails/concerns/performable'
3
+ require 'dry-initializer-rails'
4
+
5
+ module AuxiliaryRails
6
+ module Application
7
+ # @abstract
8
+ class Command
9
+ extend Dry::Initializer
10
+ include AuxiliaryRails::Concerns::Performable
11
+
12
+ class << self
13
+ # @!method param(name, options = {})
14
+ # Defines param using <tt>Dry::Initializer</tt> format.
15
+ #
16
+ # @see Dry::Initializer
17
+ # @see https://dry-rb.org/gems/dry-initializer/3.0/params-and-options/
18
+ #
19
+ # @param name [Symbol]
20
+ # @param options [Hash]
21
+
22
+ # @!method option(name, options = {})
23
+ # Defines option using <tt>Dry::Initializer</tt> format.
24
+
25
+ # @see Dry::Initializer
26
+ # @see https://dry-rb.org/gems/dry-initializer/3.0/params-and-options/
27
+ #
28
+ # @param name [Symbol]
29
+ # @param options [Hash]
30
+
31
+ # @!method call(*args, **kws)
32
+ # @see AuxiliaryRails::Corcerns::Callable
33
+ # @return [self]
34
+
35
+ # Defines `scope` for <tt>ActiveModel::Translation</tt>
36
+ #
37
+ # @return [Symbol]
38
+ def i18n_scope
39
+ :commands
40
+ end
41
+ end
42
+
43
+ protected
44
+
45
+ # Shortcut reader for attributes defined by <tt>Dry::Initializer</tt>
46
+ #
47
+ # @return [Hash]
48
+ def arguments
49
+ self.class.dry_initializer.attributes(self)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,50 @@
1
+ module AuxiliaryRails
2
+ module Application
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
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
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,31 @@
1
+ require 'active_model'
2
+ require 'auxiliary_rails/concerns/performable'
3
+
4
+ module AuxiliaryRails
5
+ module Application
6
+ # @abstract
7
+ class Form
8
+ include ActiveModel::Model
9
+ include ActiveModel::Attributes
10
+ include ActiveModel::AttributeAssignment
11
+ include AuxiliaryRails::Concerns::Performable
12
+
13
+ class << self
14
+ # Defines `scope` for <tt>ActiveModel::Translation</tt>
15
+ #
16
+ # @return [Symbol]
17
+ def i18n_scope
18
+ :forms
19
+ end
20
+ end
21
+
22
+ # Indicates object persistence.
23
+ #
24
+ # In case of form as performable object that means that form
25
+ # was executed with success.
26
+ def persisted?
27
+ performable_status == true
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,75 @@
1
+ require 'auxiliary_rails/concerns/callable'
2
+ require 'auxiliary_rails/concerns/errorable'
3
+ require 'dry/core/class_attributes'
4
+ require 'dry-initializer'
5
+
6
+ module AuxiliaryRails
7
+ module Application
8
+ # @abstract
9
+ class Query
10
+ extend Dry::Core::ClassAttributes
11
+ extend Dry::Initializer
12
+ include AuxiliaryRails::Concerns::Callable
13
+ include AuxiliaryRails::Concerns::Errorable
14
+
15
+ defines :default_relation
16
+
17
+ option :relation, default: proc {}
18
+
19
+ def call
20
+ ensure_proper_relation_types!
21
+
22
+ perform
23
+
24
+ if !queriable_object?(query)
25
+ error!('Invalid class of resulted query')
26
+ end
27
+
28
+ query
29
+ end
30
+
31
+ # @abstract
32
+ def perform
33
+ raise NotImplementedError
34
+ end
35
+
36
+ def method_missing(method_name, *args, &block)
37
+ super unless query.respond_to?(method_name)
38
+
39
+ query.send(method_name, *args, &block)
40
+ end
41
+
42
+ def respond_to_missing?(method_name, include_private = false)
43
+ query.respond_to?(method_name) || super
44
+ end
45
+
46
+ private
47
+
48
+ # rubocop:disable Style/GuardClause
49
+ def ensure_proper_relation_types!
50
+ if self.class.default_relation.nil?
51
+ error!('Undefined `default_relation`')
52
+ end
53
+ if !queriable_object?(self.class.default_relation)
54
+ error!('Invalid class of `default_relation`')
55
+ end
56
+ if !relation.nil? && !queriable_object?(relation)
57
+ error!('Invalid class of `relation` option')
58
+ end
59
+ end
60
+ # rubocop:enable Style/GuardClause
61
+
62
+ def queriable_object?(object)
63
+ object.is_a?(ActiveRecord::Relation)
64
+ end
65
+
66
+ def query(scoped_query = nil)
67
+ @query ||= (relation || self.class.default_relation)
68
+
69
+ @query = scoped_query unless scoped_query.nil?
70
+
71
+ @query
72
+ end
73
+ end
74
+ end
75
+ end
@@ -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
@@ -6,6 +6,10 @@ module AuxiliaryRails
6
6
 
7
7
  TEMPLATES_DIR =
8
8
  File.expand_path("#{__dir__}/../../templates/")
9
+ REPOSITORY_URL =
10
+ 'https://raw.githubusercontent.com/ergoserv/' \
11
+ 'auxiliary_rails/develop/templates'
12
+ .freeze
9
13
 
10
14
  desc 'new APP_PATH', 'Create Rails application from template'
11
15
  long_desc <<-LONGDESC
@@ -17,20 +21,29 @@ module AuxiliaryRails
17
21
  option :database,
18
22
  default: 'postgresql',
19
23
  type: :string
20
- option :template_name,
24
+ option :template,
21
25
  default: 'elementary',
22
26
  type: :string
27
+ option :develop,
28
+ default: false,
29
+ type: :boolean
23
30
  def new(app_path)
24
31
  run "rails new #{app_path} " \
25
- '--skip-action-cable --skip-coffee --skip-test ' \
26
32
  "--database=#{options[:database]} " \
27
- "--template=#{rails_template_path(options[:template_name])}"
33
+ "--template=#{rails_template_path(options[:template])} " \
34
+ '--skip-action-cable ' \
35
+ '--skip-coffee ' \
36
+ '--skip-test '
28
37
  end
29
38
 
30
39
  private
31
40
 
32
- def rails_template_path(template_name)
33
- "#{TEMPLATES_DIR}/rails/#{template_name}.rb"
41
+ def rails_template_path(template)
42
+ if options[:develop] == true
43
+ "#{REPOSITORY_URL}/rails/#{template}.rb"
44
+ else
45
+ "#{TEMPLATES_DIR}/rails/#{template}.rb"
46
+ end
34
47
  end
35
48
  end
36
49
  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
@@ -0,0 +1,22 @@
1
+ module AuxiliaryRails
2
+ module Concerns
3
+ module Errorable
4
+ extend ActiveSupport::Concern
5
+
6
+ class_methods do
7
+ def error_class
8
+ if Object.const_defined?(:ApplicationError)
9
+ ApplicationError
10
+ else
11
+ AuxiliaryRails::Application::Error
12
+ end
13
+ end
14
+ end
15
+
16
+ def error!(message = nil)
17
+ message ||= "`#{self.class}` raised error."
18
+ raise self.class.error_class, message
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,120 @@
1
+ require 'active_support/concern'
2
+ require 'auxiliary_rails/concerns/callable'
3
+ require 'auxiliary_rails/concerns/errorable'
4
+
5
+ module AuxiliaryRails
6
+ module Concerns
7
+ module Performable
8
+ extend ActiveSupport::Concern
9
+ include ActiveModel::Validations
10
+ include AuxiliaryRails::Concerns::Callable
11
+ include AuxiliaryRails::Concerns::Errorable
12
+
13
+ def call(options = {})
14
+ ensure_empty_status!
15
+
16
+ if options[:validate!] == true
17
+ validate!
18
+ elsif options[:validate] != false && invalid?
19
+ return failure!
20
+ end
21
+
22
+ perform
23
+
24
+ ensure_execution!
25
+ self
26
+ end
27
+
28
+ # Describes business logic.
29
+ #
30
+ # Method <b>should always</b> return <tt>success!</tt>
31
+ # or <tt>failure!</tt> methods in order pro provide further
32
+ # correct method chaining.
33
+ #
34
+ # @abstract
35
+ # @return [self]
36
+ def perform
37
+ raise NotImplementedError
38
+ end
39
+
40
+ def failure?
41
+ status?(:failure)
42
+ end
43
+
44
+ def status?(value)
45
+ ensure_execution!
46
+
47
+ performable_status == value&.to_sym
48
+ end
49
+
50
+ def success?
51
+ status?(:success)
52
+ end
53
+
54
+ # Provides ability to execude block of the code depending on
55
+ # command execution status
56
+ #
57
+ # @param status [Symbol] Desired command status
58
+ # @param &block Code to be executed if status matches
59
+ # @return [self]
60
+ def on(status, &block)
61
+ yield(self) if status?(status) && block
62
+
63
+ self
64
+ end
65
+
66
+ protected
67
+
68
+ attr_accessor :performable_status
69
+
70
+ # @raise [AuxiliaryRails::Application::Error]
71
+ # Error happens if command contains any errors.
72
+ # @return [nil]
73
+ def ensure_empty_errors!
74
+ return if errors.empty?
75
+
76
+ error!("`#{self.class}` contains errors.")
77
+ end
78
+
79
+ def ensure_empty_status!
80
+ return if performable_status.nil?
81
+
82
+ error!("`#{self.class}` was already executed.")
83
+ end
84
+
85
+ def ensure_execution!
86
+ return if performable_status.present?
87
+
88
+ error!("`#{self.class}` was not executed yet.")
89
+ end
90
+
91
+ # Sets command's status to <tt>failure</tt>.
92
+ #
93
+ # @return [self]
94
+ def failure!(message = nil, options = {})
95
+ ensure_empty_status!
96
+
97
+ errors.add(:base, message, options) if message.present?
98
+
99
+ self.performable_status = :failure
100
+ self
101
+ end
102
+
103
+ # Sets command's status to <tt>success</tt>.
104
+ #
105
+ # @return [self]
106
+ def success!
107
+ ensure_empty_errors!
108
+ ensure_empty_status!
109
+
110
+ self.performable_status = :success
111
+ self
112
+ end
113
+
114
+ # Shortcut for <tt>ActiveRecord::Base.transaction</tt>
115
+ def transaction(&block)
116
+ ActiveRecord::Base.transaction(&block) if block
117
+ end
118
+ end
119
+ end
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.2.0'.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