Class: Easyop::Ctx
- Inherits:
-
Object
- Object
- Easyop::Ctx
- Defined in:
- lib/easyop/ctx.rb
Overview
Easyop::Ctx is the shared data bag passed through an operation (or flow of operations). It replaces Interactor’s Context with a faster, Hash-backed implementation that avoids the deprecated OpenStruct.
It doubles as the result object returned from Operation.call — the caller inspects ctx.success? / ctx.failure? and reads output attributes directly.
Key API:
ctx.fail! # mark failed (raises Ctx::Failure internally)
ctx.fail!(error: "Boom!") # set attrs AND fail
ctx.success? / ctx.ok? # true unless fail! was called
ctx.failure? / ctx.failed? # true after fail!
ctx.error # shortcut for ctx[:error]
ctx.errors # shortcut for ctx[:errors] ({} by default)
ctx[:key] / ctx.key # attribute read
ctx[:key] = v / ctx.key = v # attribute write
ctx.merge!(hash) # bulk-set attributes
ctx.on_success { |ctx| ... } # chainable callback
ctx.on_failure { |ctx| ... } # chainable callback
Defined Under Namespace
Classes: Failure
Class Method Summary collapse
-
.build(attrs = {}) ⇒ Object
── Construction ────────────────────────────────────────────────────────.
Instance Method Summary collapse
-
#[](key) ⇒ Object
── Attribute access ─────────────────────────────────────────────────────.
- #[]=(key, val) ⇒ Object
-
#called!(operation) ⇒ Object
Called by Flow to track which operations have run.
-
#deconstruct_keys(keys) ⇒ Object
Supports: case result; in { success: true, user: } …
-
#error ⇒ Object
── Error conveniences ───────────────────────────────────────────────────.
- #error=(msg) ⇒ Object
- #errors ⇒ Object
- #errors=(hash) ⇒ Object
-
#fail!(attrs = {}) ⇒ Object
Mark the operation as failed.
- #failure? ⇒ Boolean (also: #failed?)
-
#initialize(attrs = {}) ⇒ Ctx
constructor
A new instance of Ctx.
- #inspect ⇒ Object
- #key?(key) ⇒ Boolean
- #merge!(attrs = {}) ⇒ Object
-
#method_missing(name, *args) ⇒ Object
── Dynamic attribute access (method_missing) ─────────────────────────────.
- #on_failure {|_self| ... } ⇒ Object
-
#on_success {|_self| ... } ⇒ Object
── Chainable result callbacks ────────────────────────────────────────────.
- #respond_to_missing?(name, include_private = false) ⇒ Boolean
-
#rollback! ⇒ Object
Roll back already-called operations in reverse order.
-
#slice(*keys) ⇒ Object
Returns a plain Hash with only the specified keys.
-
#success? ⇒ Boolean
(also: #ok?)
── Status ───────────────────────────────────────────────────────────────.
- #to_h ⇒ Object
Constructor Details
#initialize(attrs = {}) ⇒ Ctx
Returns a new instance of Ctx.
40 41 42 43 44 45 46 |
# File 'lib/easyop/ctx.rb', line 40 def initialize(attrs = {}) @attributes = {} @failure = false @rolled_back = false @called = [] # interactors already run (for rollback) attrs.each { |k, v| self[k] = v } end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args) ⇒ Object
── Dynamic attribute access (method_missing) ─────────────────────────────
161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/easyop/ctx.rb', line 161 def method_missing(name, *args) key = name.to_s if key.end_with?("=") self[key.chomp("=")] = args.first elsif key.end_with?("?") base = key.chomp("?").to_sym return !!self[base] elsif @attributes.key?(name.to_sym) self[name] else super end end |
Class Method Details
.build(attrs = {}) ⇒ Object
── Construction ────────────────────────────────────────────────────────
35 36 37 38 |
# File 'lib/easyop/ctx.rb', line 35 def self.build(attrs = {}) return attrs if attrs.is_a?(self) new(attrs) end |
Instance Method Details
#[](key) ⇒ Object
── Attribute access ─────────────────────────────────────────────────────
50 51 52 |
# File 'lib/easyop/ctx.rb', line 50 def [](key) @attributes[key.to_sym] end |
#[]=(key, val) ⇒ Object
54 55 56 |
# File 'lib/easyop/ctx.rb', line 54 def []=(key, val) @attributes[key.to_sym] = val end |
#called!(operation) ⇒ Object
Called by Flow to track which operations have run.
134 135 136 137 |
# File 'lib/easyop/ctx.rb', line 134 def called!(operation) @called << operation self end |
#deconstruct_keys(keys) ⇒ Object
Supports: case result; in { success: true, user: } …
152 153 154 155 156 157 |
# File 'lib/easyop/ctx.rb', line 152 def deconstruct_keys(keys) base = { success: success?, failure: failure? } base.merge(@attributes).then do |all| keys ? all.slice(*keys) : all end end |
#error ⇒ Object
── Error conveniences ───────────────────────────────────────────────────
103 104 105 |
# File 'lib/easyop/ctx.rb', line 103 def error self[:error] end |
#error=(msg) ⇒ Object
107 108 109 |
# File 'lib/easyop/ctx.rb', line 107 def error=(msg) self[:error] = msg end |
#errors ⇒ Object
111 112 113 |
# File 'lib/easyop/ctx.rb', line 111 def errors self[:errors] || {} end |
#errors=(hash) ⇒ Object
115 116 117 |
# File 'lib/easyop/ctx.rb', line 115 def errors=(hash) self[:errors] = hash end |
#fail!(attrs = {}) ⇒ Object
Mark the operation as failed. Accepts an optional hash of attributes to merge into ctx before raising (e.g. error:, errors:).
95 96 97 98 99 |
# File 'lib/easyop/ctx.rb', line 95 def fail!(attrs = {}) merge!(attrs) @failure = true raise Failure, self end |
#failure? ⇒ Boolean Also known as: failed?
86 87 88 |
# File 'lib/easyop/ctx.rb', line 86 def failure? @failure end |
#inspect ⇒ Object
182 183 184 185 |
# File 'lib/easyop/ctx.rb', line 182 def inspect status = @failure ? "FAILED" : "ok" "#<Easyop::Ctx #{@attributes.inspect} [#{status}]>" end |
#key?(key) ⇒ Boolean
67 68 69 |
# File 'lib/easyop/ctx.rb', line 67 def key?(key) @attributes.key?(key.to_sym) end |
#merge!(attrs = {}) ⇒ Object
58 59 60 61 |
# File 'lib/easyop/ctx.rb', line 58 def merge!(attrs = {}) attrs.each { |k, v| self[k] = v } self end |
#on_failure {|_self| ... } ⇒ Object
126 127 128 129 |
# File 'lib/easyop/ctx.rb', line 126 def on_failure yield self if failure? self end |
#on_success {|_self| ... } ⇒ Object
── Chainable result callbacks ────────────────────────────────────────────
121 122 123 124 |
# File 'lib/easyop/ctx.rb', line 121 def on_success yield self if success? self end |
#respond_to_missing?(name, include_private = false) ⇒ Boolean
175 176 177 178 179 180 |
# File 'lib/easyop/ctx.rb', line 175 def respond_to_missing?(name, include_private = false) key = name.to_s return true if key.end_with?("=") return true if key.end_with?("?") @attributes.key?(name.to_sym) || super end |
#rollback! ⇒ Object
Roll back already-called operations in reverse order. Errors in individual rollbacks are swallowed to ensure all run.
141 142 143 144 145 146 147 |
# File 'lib/easyop/ctx.rb', line 141 def rollback! return if @rolled_back @rolled_back = true @called.reverse_each do |op| op.rollback rescue nil end end |
#slice(*keys) ⇒ Object
Returns a plain Hash with only the specified keys.
72 73 74 75 76 77 |
# File 'lib/easyop/ctx.rb', line 72 def slice(*keys) keys.each_with_object({}) do |k, h| sym = k.to_sym h[sym] = @attributes[sym] if @attributes.key?(sym) end end |
#success? ⇒ Boolean Also known as: ok?
── Status ───────────────────────────────────────────────────────────────
81 82 83 |
# File 'lib/easyop/ctx.rb', line 81 def success? !@failure end |
#to_h ⇒ Object
63 64 65 |
# File 'lib/easyop/ctx.rb', line 63 def to_h @attributes.dup end |