Module: RailsStuff::Statusable

Defined in:
lib/rails_stuff/statusable.rb

Overview

Basic helpers to work with ‘status`-like field.

For every status value it provides:

  • scopes with status name (eg. ‘.rejected`, ’.not_rejected’)

  • inquiry method to check status (eg. ‘#rejected?`)

  • bang method to update status (eg. ‘#rejected!`)

It also provides:

  • translation helpers (‘acttivemodel_translation` gem required)

  • inclusion validator

  • string/symbol agnostic ‘#status=`

  • ‘#status_sym`

  • ‘status_select_options` helper.

Defined Under Namespace

Modules: MethodsGenerator

Instance Method Summary collapse

Instance Method Details

#has_status_field(field = :status, statuses = nil, **options) ⇒ Object

Defines all helpers working with ‘field` (default to `status`). List of values can be given as second argument, otherwise it’ll be read from const with pluralized name of ‘field` (eg. default to STATUSES).

#### Options

  • ‘prefix` - used to prefix value-named helpers.

    # this defines #shipped?, #shipped! methods
    has_status_field :delivery_status, i(shipped delivered)
    
    # this defines #delivery_shipped?, #delivery_shipped! methods
    has_status_field :delivery_status, i(shipped delivered), prefix: :delivery
    
  • ‘validate` - additional options for validatior. `false` to disable it.



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/rails_stuff/statusable.rb', line 34

def has_status_field(field = :status, statuses = nil, **options) # rubocop:disable AbcSize
  statuses ||= const_get(field.to_s.pluralize.upcase)
  prefix = options[:prefix]

  if options[:validate] != false
    validates_inclusion_of field,
      {in: statuses.map(&:to_s)}.merge!(options.fetch(:validate, {}))
  end

  statusable_methods.generate_field_methods field, statuses

  # Scope with given status. Useful for has_scope.
  scope "with_#{field}", ->(status) { where(field => status) }

  statuses.map(&:to_s).each do |status_name|
    # Scopes for every status.
    scope "#{prefix}#{status_name}", -> { where(field => status_name) }
    scope "not_#{prefix}#{status_name}", -> { where.not(field => status_name) }
    statusable_methods.status_accessor field, status_name, prefix
  end
end

#statusable_methodsObject

Module to hold generated methods.



57
58
59
60
61
62
63
64
65
# File 'lib/rails_stuff/statusable.rb', line 57

def statusable_methods
  # Include generated methods with a module, not right in class.
  @statusable_methods ||= Module.new.tap do |m|
    m.const_set :ClassMethods, Module.new
    m.extend MethodsGenerator
    include m
    extend m::ClassMethods
  end
end