Class: Operandi::Messages

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/operandi/messages.rb

Overview

Collection of error or warning messages, organized by key.

Examples:

Adding and accessing errors

errors.add(:name, "can't be blank")
errors.add(:email, "is invalid")
errors[:name]  # => [#<Message key: :name, text: "can't be blank">]
errors.to_h    # => { name: ["can't be blank"], email: ["is invalid"] }

Instance Method Summary collapse

Constructor Details

#initialize(config = {}, service:) ⇒ Messages

Initialize a new messages collection.

Parameters:

  • config (Hash) (defaults to: {})

    configuration options

  • service (Base)

    service instance that owns this collection

Options Hash (config):

  • :break_on_add (Boolean)

    stop execution when message added

  • :raise_on_add (Boolean)

    raise exception when message added

  • :rollback_on_add (Boolean)

    rollback transaction when message added



59
60
61
62
63
64
# File 'lib/operandi/messages.rb', line 59

def initialize(config = {}, service:)
  @break = false
  @config = config
  @messages = {}
  @service = service
end

Instance Method Details

#[](key) ⇒ Array<Message>?

Get messages for a specific key.

Parameters:

  • key (Symbol)

    the key to look up

Returns:

  • (Array<Message>, nil)

    array of messages or nil



# File 'lib/operandi/messages.rb', line 14

#add(key, texts, opts = {}) ⇒ void

This method returns an undefined value.

Add a message to the collection.

Examples:

Add a single error

errors.add(:name, "can't be blank")

Add multiple errors

errors.add(:email, ["is invalid", "is already taken"])

Parameters:

  • key (Symbol)

    the key/field for this message

  • texts (String, Array<String>, Message)

    the message text(s) to add

  • opts (Hash) (defaults to: {})

    additional options

Options Hash (opts):

  • :break (Boolean)

    override break behavior for this message

  • :rollback (Boolean)

    override rollback behavior for this message

Raises:



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/operandi/messages.rb', line 88

def add(key, texts, opts = {})
  raise_error("Error must be a non-empty string") unless texts

  message = nil

  [*texts].each do |text|
    message = text.is_a?(Message) ? text : Message.new(key, text, opts)

    raise_error("Error must be a non-empty string") unless valid_error_text?(message.text)

    @messages[key] ||= []
    @messages[key] << message
  end

  raise!(message)
  break!(opts.key?(:break) ? opts[:break] : message.break?)
  rollback!(opts.key?(:rollback) ? opts[:rollback] : message.rollback?) if !opts.key?(:last) || opts[:last]
end

#any?Boolean

Check if there are any messages.

Returns:

  • (Boolean)

    true if messages exist



# File 'lib/operandi/messages.rb', line 19

#break?Boolean

Check if step execution should stop.

Returns:

  • (Boolean)

    true if a message triggered a break



110
111
112
# File 'lib/operandi/messages.rb', line 110

def break?
  @break
end

#copy_from(entity, opts = {}) ⇒ void Also known as: from_record

This method returns an undefined value.

Copy messages from another source.

Examples:

Copy from ActiveRecord model

errors.copy_from(user) # copies user.errors

Copy from another service

errors.copy_from(child_service)

Parameters:

  • entity (ActiveRecord::Base, Base, Hash, #each)

    source to copy from

  • opts (Hash) (defaults to: {})

    options to pass to each added message

Raises:



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/operandi/messages.rb', line 126

def copy_from(entity, opts = {})
  if defined?(ActiveRecord::Base) && entity.is_a?(ActiveRecord::Base)
    copy_from(entity.errors.messages, opts)
  elsif entity.is_a?(Operandi::Base)
    copy_from(entity.errors, opts)
  elsif entity.respond_to?(:each)
    last_index = entity.size - 1

    entity.each_with_index do |(key, message), index|
      add(key, message, opts.merge(last: index == last_index))
    end
  else
    raise_error("Don't know how to import errors from #{entity}")
  end
end

#countInteger

Get total count of all messages across all keys.

Returns:

  • (Integer)

    total number of messages



69
70
71
# File 'lib/operandi/messages.rb', line 69

def count
  @messages.values.sum(&:size)
end

#empty?Boolean

Check if the collection is empty.

Returns:

  • (Boolean)

    true if no messages



# File 'lib/operandi/messages.rb', line 23

#key?(key) ⇒ Boolean Also known as: has_key?

Check if a key has messages.

Parameters:

  • key (Symbol)

    the key to check

Returns:

  • (Boolean)

    true if key has messages



39
40
41
42
43
44
45
46
47
48
49
# File 'lib/operandi/messages.rb', line 39

def_delegators :@messages,
:[],
:any?,
:empty?,
:size,
:keys,
:values,
:each,
:each_with_index,
:each_with_object,
:key?

#keysArray<Symbol>

Get all keys with messages.

Returns:

  • (Array<Symbol>)

    array of keys



# File 'lib/operandi/messages.rb', line 31

#sizeInteger

Get number of keys with messages.

Returns:

  • (Integer)

    number of keys



# File 'lib/operandi/messages.rb', line 27

#to_hHash{Symbol => Array<String>}

Convert messages to a hash with string values.

Returns:

  • (Hash{Symbol => Array<String>})

    messages as hash



146
147
148
# File 'lib/operandi/messages.rb', line 146

def to_h
  @messages.to_h.transform_values { |value| value.map(&:to_s) }
end