state_machines-activerecord 0.100.0 → 0.102.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.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 710df8aa712f81e7a44c6646930c1c9f4507eb5423ca752d4359fe09f27ebb2e
|
|
4
|
+
data.tar.gz: c881a6d3b25aa45df35c0d62473f3b8a1dfed4cf7298d1657bebdba8fa086468
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 866e2c089a9b52d214f37094021a7a1b0d10b775ce844c21eb42df7827c05fcd023b811a41cb1994215231806271825cf5b150b896de8d1d3756576525266c9e
|
|
7
|
+
data.tar.gz: 6aa52b30f96174a033db1a9f189fe233327baf8b195ded225baad3f687952d0d210fa16430e629b22f031e42359f769dab3d2aebb3addae8ddec39fdf98dc6bb
|
data/README.md
CHANGED
|
@@ -77,7 +77,108 @@ Vehicle.with_state(params[:state]) # Returns all vehicles if par
|
|
|
77
77
|
Vehicle.where(color: 'red').with_state(nil) # Returns all red vehicles (chainable)
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
## Rails Enum Integration
|
|
81
|
+
|
|
82
|
+
When your ActiveRecord model uses Rails enums and defines a state machine on the same attribute, this gem automatically detects the conflict and provides seamless integration. This prevents method name collisions between Rails enum methods and state machine methods.
|
|
83
|
+
|
|
84
|
+
### Auto-Detection and Conflict Resolution
|
|
85
|
+
|
|
86
|
+
```ruby
|
|
87
|
+
class Order < ApplicationRecord
|
|
88
|
+
# Rails enum definition
|
|
89
|
+
enum :status, { pending: 0, processing: 1, completed: 2, cancelled: 3 }
|
|
90
|
+
|
|
91
|
+
# State machine on the same attribute
|
|
92
|
+
state_machine :status do
|
|
93
|
+
state :pending, :processing, :completed, :cancelled
|
|
94
|
+
|
|
95
|
+
event :process do
|
|
96
|
+
transition pending: :processing
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
event :complete do
|
|
100
|
+
transition processing: :completed
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
event :cancel do
|
|
104
|
+
transition [:pending, :processing] => :cancelled
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
When enum integration is detected, the gem automatically:
|
|
111
|
+
- Preserves original Rails enum methods (`pending?`, `processing?`, etc.)
|
|
112
|
+
- Generates prefixed state machine methods to avoid conflicts (`status_pending?`, `status_processing?`, etc.)
|
|
113
|
+
- Creates prefixed scope methods (`Order.status_pending`, `Order.status_processing`, etc.)
|
|
114
|
+
|
|
115
|
+
### Available Methods
|
|
116
|
+
|
|
117
|
+
**Original Rails enum methods (preserved):**
|
|
118
|
+
```ruby
|
|
119
|
+
order = Order.create(status: :pending)
|
|
120
|
+
order.pending? # => true (Rails enum method)
|
|
121
|
+
order.processing? # => false (Rails enum method)
|
|
122
|
+
order.processing! # Sets status to :processing (Rails enum method)
|
|
123
|
+
|
|
124
|
+
Order.pending # Rails enum scope
|
|
125
|
+
Order.processing # Rails enum scope
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Generated state machine methods (prefixed):**
|
|
129
|
+
```ruby
|
|
130
|
+
# Predicate methods
|
|
131
|
+
order.status_pending? # => true (state machine method)
|
|
132
|
+
order.status_processing? # => false (state machine method)
|
|
133
|
+
order.status_completed? # => false (state machine method)
|
|
134
|
+
|
|
135
|
+
# Bang methods (for conflict resolution only)
|
|
136
|
+
# These are placeholders and raise runtime errors
|
|
137
|
+
order.status_processing! # => raises RuntimeError
|
|
138
|
+
|
|
139
|
+
# Scope methods
|
|
140
|
+
Order.status_pending # State machine scope
|
|
141
|
+
Order.status_processing # State machine scope
|
|
142
|
+
Order.not_status_pending # Negative state machine scope
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Introspection API
|
|
146
|
+
|
|
147
|
+
The integration provides a comprehensive introspection API for advanced use cases:
|
|
148
|
+
|
|
149
|
+
```ruby
|
|
150
|
+
machine = Order.state_machine(:status)
|
|
151
|
+
|
|
152
|
+
# Check if enum integration is enabled
|
|
153
|
+
machine.enum_integrated? # => true
|
|
154
|
+
|
|
155
|
+
# Get the Rails enum mapping
|
|
156
|
+
machine.enum_mapping # => {"pending"=>0, "processing"=>1, "completed"=>2, "cancelled"=>3}
|
|
157
|
+
|
|
158
|
+
# Get original Rails enum methods that were preserved
|
|
159
|
+
machine.original_enum_methods
|
|
160
|
+
# => ["pending?", "processing?", "completed?", "cancelled?", "pending!", "processing!", ...]
|
|
161
|
+
|
|
162
|
+
# Get state machine methods that were generated
|
|
163
|
+
machine.state_machine_methods
|
|
164
|
+
# => ["status_pending?", "status_processing?", "status_completed?", "status_cancelled?", ...]
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
### Requirements for Enum Integration
|
|
169
|
+
|
|
170
|
+
- The state machine attribute must match an existing Rails enum attribute
|
|
171
|
+
- Auto-detection is enabled by default when this condition is met
|
|
172
|
+
|
|
173
|
+
### Configuration Options
|
|
174
|
+
|
|
175
|
+
The enum integration supports several configuration options:
|
|
176
|
+
|
|
177
|
+
- `prefix` (default: true) - Adds a prefix to generated methods to avoid conflicts
|
|
178
|
+
- `suffix` (default: false) - Alternative naming strategy using suffixes instead of prefixes
|
|
179
|
+
- `scopes` (default: true) - Controls whether state machine scopes are generated
|
|
180
|
+
|
|
181
|
+
## State driven validations
|
|
81
182
|
|
|
82
183
|
As mentioned in `StateMachines::Machine#state`, you can define behaviors,
|
|
83
184
|
like validations, that only execute for certain states. One *important*
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module StateMachines
|
|
4
|
+
module Type
|
|
5
|
+
# Custom ActiveRecord attribute type for state machine attributes backed by
|
|
6
|
+
# integer columns. Handles bidirectional conversion between state name strings
|
|
7
|
+
# (used internally by the state machine) and integer values (stored in the DB).
|
|
8
|
+
#
|
|
9
|
+
# States without explicit integer values are mapped by their index position
|
|
10
|
+
# in the states collection (0, 1, 2, …). States with an explicit integer
|
|
11
|
+
# value (e.g. state :pending, value: 2) use that value directly.
|
|
12
|
+
class Integer < ::ActiveRecord::Type::Value
|
|
13
|
+
def initialize(states)
|
|
14
|
+
@states = states
|
|
15
|
+
super()
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# integer from DB → state name string
|
|
19
|
+
def deserialize(value)
|
|
20
|
+
return nil if value.nil?
|
|
21
|
+
int_val = value.to_i
|
|
22
|
+
state = named_states.detect { |s| state_integer(s) == int_val }
|
|
23
|
+
state ? state.name.to_s : value
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# assignment (symbol / string / integer) → state name string (in-memory)
|
|
27
|
+
def cast(value)
|
|
28
|
+
return nil if value.nil?
|
|
29
|
+
state = named_states.detect { |s| s.name.to_s == value.to_s }
|
|
30
|
+
state ||= named_states.detect { |s| state_integer(s) == value.to_i } if value.respond_to?(:to_i)
|
|
31
|
+
state ? state.name.to_s : value.to_s
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# state name string → integer for DB write
|
|
35
|
+
def serialize(value)
|
|
36
|
+
return nil if value.nil?
|
|
37
|
+
state = named_states.detect { |s| s.name.to_s == value.to_s }
|
|
38
|
+
state ? state_integer(state) : value
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def type
|
|
42
|
+
:integer
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
# All non-nil states in definition order — not memoized because states are
|
|
48
|
+
# added to the collection after the type is instantiated.
|
|
49
|
+
def named_states
|
|
50
|
+
@states.reject { |s| s.name.nil? }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Returns the integer to use for storage:
|
|
54
|
+
# - explicit integer value if set (e.g. state :pending, value: 2)
|
|
55
|
+
# - otherwise the index position among named states
|
|
56
|
+
def state_integer(state)
|
|
57
|
+
state.value.is_a?(::Integer) ? state.value : named_states.index(state)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'state_machines-activemodel'
|
|
2
4
|
require 'active_record'
|
|
3
5
|
require 'state_machines/integrations/active_record/version'
|
|
6
|
+
require 'state_machines/integrations/active_record/type/integer'
|
|
4
7
|
|
|
5
8
|
module StateMachines
|
|
6
9
|
module Integrations # :nodoc:
|
|
@@ -194,7 +197,8 @@ module StateMachines
|
|
|
194
197
|
# example, assuming there's a validation on a field called +name+ on the class:
|
|
195
198
|
#
|
|
196
199
|
# vehicle = Vehicle.new
|
|
197
|
-
# vehicle.ignite! # => StateMachines::InvalidTransition: Cannot transition state via :ignite from :parked
|
|
200
|
+
# vehicle.ignite! # => StateMachines::InvalidTransition: Cannot transition state via :ignite from :parked
|
|
201
|
+
# # (Reason(s): Name cannot be blank)
|
|
198
202
|
#
|
|
199
203
|
# == Scopes
|
|
200
204
|
#
|
|
@@ -368,6 +372,251 @@ module StateMachines
|
|
|
368
372
|
|
|
369
373
|
# The default options to use for state machines using this integration
|
|
370
374
|
@defaults = { action: :save, use_transactions: true }
|
|
375
|
+
|
|
376
|
+
# Machine-specific methods for enum integration
|
|
377
|
+
module MachineMethods
|
|
378
|
+
# Enum integration metadata storage
|
|
379
|
+
attr_accessor :enum_integration
|
|
380
|
+
|
|
381
|
+
# Hook called after machine initialization
|
|
382
|
+
def after_initialize
|
|
383
|
+
super
|
|
384
|
+
initialize_enum_integration
|
|
385
|
+
register_integer_type if integer_column? && !enum_integrated?
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
# Check if enum integration should be enabled for this machine
|
|
389
|
+
def detect_enum_integration
|
|
390
|
+
return nil unless owner_class.defined_enums.key?(attribute.to_s)
|
|
391
|
+
|
|
392
|
+
# For now, auto-detect enum and enable basic integration
|
|
393
|
+
# Later we can add explicit configuration options
|
|
394
|
+
{
|
|
395
|
+
enabled: true,
|
|
396
|
+
prefix: true,
|
|
397
|
+
suffix: false,
|
|
398
|
+
scopes: true,
|
|
399
|
+
enum_values: owner_class.defined_enums[attribute.to_s] || {},
|
|
400
|
+
original_enum_methods: detect_existing_enum_methods,
|
|
401
|
+
state_machine_methods: []
|
|
402
|
+
}
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
# Initialize enum integration if enum is detected
|
|
406
|
+
def initialize_enum_integration
|
|
407
|
+
detected_config = detect_enum_integration
|
|
408
|
+
return unless detected_config
|
|
409
|
+
|
|
410
|
+
# Store enum integration metadata
|
|
411
|
+
self.enum_integration = detected_config
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
# Override state method to trigger method generation after states are defined
|
|
415
|
+
def state(*, &)
|
|
416
|
+
result = super
|
|
417
|
+
|
|
418
|
+
# Generate methods after each state addition if enum integration is enabled
|
|
419
|
+
generate_state_machine_methods if enum_integrated?
|
|
420
|
+
|
|
421
|
+
result
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
# Check if this machine has enum integration enabled
|
|
425
|
+
def enum_integrated?
|
|
426
|
+
enum_integration && enum_integration[:enabled]
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
# Get the enum mapping for this attribute
|
|
430
|
+
def enum_mapping
|
|
431
|
+
return {} unless enum_integrated?
|
|
432
|
+
|
|
433
|
+
enum_integration[:enum_values] || {}
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
# Get list of original enum methods that were preserved
|
|
437
|
+
def original_enum_methods
|
|
438
|
+
return [] unless enum_integrated?
|
|
439
|
+
|
|
440
|
+
enum_integration[:original_enum_methods] || []
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
# Get list of state machine methods that were generated
|
|
444
|
+
def state_machine_methods
|
|
445
|
+
return [] unless enum_integrated?
|
|
446
|
+
|
|
447
|
+
enum_integration[:state_machine_methods] || []
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
private
|
|
451
|
+
|
|
452
|
+
# Returns true when the state machine attribute is backed by an integer column
|
|
453
|
+
def integer_column?
|
|
454
|
+
return false unless owner_class.respond_to?(:type_for_attribute)
|
|
455
|
+
return false unless owner_class.connected? && owner_class.table_exists?
|
|
456
|
+
|
|
457
|
+
owner_class.type_for_attribute(attribute.to_s).type == :integer
|
|
458
|
+
rescue ::ActiveRecord::StatementInvalid, ::ActiveRecord::ConnectionNotEstablished
|
|
459
|
+
false
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
# Registers a custom AR attribute type so that integer columns transparently
|
|
463
|
+
# convert between state name strings and stored integers.
|
|
464
|
+
# Saves the raw column default first so the conflicting-default check
|
|
465
|
+
# (which fires later, during initial_state=) still compares raw integers.
|
|
466
|
+
def register_integer_type
|
|
467
|
+
@raw_integer_column_default = owner_class.column_defaults[attribute.to_s]
|
|
468
|
+
owner_class.attribute(attribute.to_s, StateMachines::Type::Integer.new(states))
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
# Detect existing enum methods for this attribute
|
|
472
|
+
def detect_existing_enum_methods
|
|
473
|
+
return [] unless owner_class.defined_enums.key?(attribute.to_s)
|
|
474
|
+
|
|
475
|
+
enum_values = owner_class.defined_enums[attribute.to_s]
|
|
476
|
+
methods = []
|
|
477
|
+
|
|
478
|
+
enum_values.each_key do |value|
|
|
479
|
+
# Predicate methods like 'active?'
|
|
480
|
+
predicate = "#{value}?"
|
|
481
|
+
methods << predicate if owner_class.method_defined?(predicate)
|
|
482
|
+
|
|
483
|
+
# Bang methods like 'active!'
|
|
484
|
+
bang_method = "#{value}!"
|
|
485
|
+
methods << bang_method if owner_class.method_defined?(bang_method)
|
|
486
|
+
|
|
487
|
+
# Scope methods (class-level)
|
|
488
|
+
methods << value.to_s if owner_class.respond_to?(value)
|
|
489
|
+
methods << "not_#{value}" if owner_class.respond_to?("not_#{value}")
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
methods
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
# Generate method name with prefix/suffix based on configuration
|
|
496
|
+
def generate_state_method_name(state_name, method_type)
|
|
497
|
+
return state_name unless enum_integrated?
|
|
498
|
+
|
|
499
|
+
config = enum_integration
|
|
500
|
+
base_name = case method_type
|
|
501
|
+
when :predicate
|
|
502
|
+
"#{state_name}?"
|
|
503
|
+
when :bang
|
|
504
|
+
"#{state_name}!"
|
|
505
|
+
else
|
|
506
|
+
state_name.to_s
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
# Apply prefix
|
|
510
|
+
if config[:prefix]
|
|
511
|
+
prefix = config[:prefix] == true ? "#{attribute}_" : "#{config[:prefix]}_"
|
|
512
|
+
base_name = "#{prefix}#{base_name}"
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
# Apply suffix
|
|
516
|
+
if config[:suffix]
|
|
517
|
+
suffix = config[:suffix] == true ? "_#{attribute}" : "_#{config[:suffix]}"
|
|
518
|
+
base_name = base_name.gsub(/(\?|!)$/, "#{suffix}\\1")
|
|
519
|
+
base_name = "#{base_name}#{suffix}" unless base_name.end_with?('?', '!')
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
base_name
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
# Generate state machine methods with conflict resolution
|
|
526
|
+
def generate_state_machine_methods
|
|
527
|
+
return unless enum_integrated?
|
|
528
|
+
|
|
529
|
+
# Initialize tracking if not already done
|
|
530
|
+
@processed_states ||= Set.new
|
|
531
|
+
enum_integration[:state_machine_methods] ||= []
|
|
532
|
+
|
|
533
|
+
# Get all states for this machine
|
|
534
|
+
states.each do |state|
|
|
535
|
+
state_name = state.name.to_s
|
|
536
|
+
next if state.nil? # Skip nil state
|
|
537
|
+
next if @processed_states.include?(state_name) # Skip already processed states
|
|
538
|
+
|
|
539
|
+
# Generate predicate method (e.g., status_pending?)
|
|
540
|
+
predicate_method = generate_state_method_name(state_name, :predicate)
|
|
541
|
+
if predicate_method != "#{state_name}?"
|
|
542
|
+
define_state_predicate_method(state_name, predicate_method)
|
|
543
|
+
track_generated_method(predicate_method)
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
# Generate bang method (e.g., status_pending!)
|
|
547
|
+
bang_method = generate_state_method_name(state_name, :bang)
|
|
548
|
+
if bang_method != "#{state_name}!"
|
|
549
|
+
define_state_bang_method(state_name, bang_method)
|
|
550
|
+
track_generated_method(bang_method)
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
# Generate scope methods (e.g., status_pending) if scopes are enabled
|
|
554
|
+
if enum_integration[:scopes]
|
|
555
|
+
scope_method = generate_state_method_name(state_name, :scope)
|
|
556
|
+
if scope_method != state_name
|
|
557
|
+
define_state_scope_method(state_name, scope_method)
|
|
558
|
+
track_generated_method(scope_method)
|
|
559
|
+
end
|
|
560
|
+
end
|
|
561
|
+
|
|
562
|
+
# Mark this state as processed
|
|
563
|
+
@processed_states.add(state_name)
|
|
564
|
+
end
|
|
565
|
+
end
|
|
566
|
+
|
|
567
|
+
# Define a prefixed predicate method for a state
|
|
568
|
+
def define_state_predicate_method(state_name, method_name)
|
|
569
|
+
machine_attribute = attribute
|
|
570
|
+
target_state_name = state_name.to_sym
|
|
571
|
+
owner_class.define_method(method_name) do
|
|
572
|
+
machine = self.class.state_machine(machine_attribute)
|
|
573
|
+
machine.states.matches?(self, target_state_name)
|
|
574
|
+
end
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
# Define a prefixed bang method for a state
|
|
578
|
+
def define_state_bang_method(state_name, method_name)
|
|
579
|
+
owner_class.define_method(method_name) do
|
|
580
|
+
# Raise an error with actionable guidance
|
|
581
|
+
raise "#{method_name} is a conflict-resolution placeholder. " \
|
|
582
|
+
"Use the original enum method '#{state_name}!' or state machine events instead."
|
|
583
|
+
end
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
# Define a prefixed scope method for a state
|
|
587
|
+
def define_state_scope_method(state_name, method_name)
|
|
588
|
+
machine_attribute = attribute
|
|
589
|
+
scope_lambda = lambda do |value = true|
|
|
590
|
+
machine = state_machine(machine_attribute)
|
|
591
|
+
state_value = machine.states[state_name.to_sym].value
|
|
592
|
+
if value
|
|
593
|
+
where(machine_attribute => state_value)
|
|
594
|
+
else
|
|
595
|
+
where.not(machine_attribute => state_value)
|
|
596
|
+
end
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
owner_class.define_singleton_method(method_name, &scope_lambda)
|
|
600
|
+
owner_class.define_singleton_method("not_#{method_name}") do
|
|
601
|
+
public_send(method_name, false)
|
|
602
|
+
end
|
|
603
|
+
end
|
|
604
|
+
|
|
605
|
+
# Track generated state machine methods for introspection
|
|
606
|
+
def track_generated_method(method_name)
|
|
607
|
+
return unless enum_integrated?
|
|
608
|
+
|
|
609
|
+
# Use a Set to ensure no duplicates
|
|
610
|
+
enum_integration[:state_machine_methods] ||= []
|
|
611
|
+
return if enum_integration[:state_machine_methods].include?(method_name)
|
|
612
|
+
|
|
613
|
+
enum_integration[:state_machine_methods] << method_name
|
|
614
|
+
end
|
|
615
|
+
end
|
|
616
|
+
|
|
617
|
+
# Include MachineMethods to make enum integration methods available on machine instances
|
|
618
|
+
include MachineMethods
|
|
619
|
+
|
|
371
620
|
class << self
|
|
372
621
|
# Classes that inherit from ActiveRecord::Base will automatically use
|
|
373
622
|
# the ActiveRecord integration.
|
|
@@ -383,8 +632,11 @@ module StateMachines
|
|
|
383
632
|
action == :save
|
|
384
633
|
end
|
|
385
634
|
|
|
386
|
-
# Gets the db default for the machine's attribute
|
|
635
|
+
# Gets the db default for the machine's attribute.
|
|
636
|
+
# For integer columns the raw pre-type-registration default is returned so
|
|
637
|
+
# that check_conflicting_attribute_default can compare integers to integers.
|
|
387
638
|
def owner_class_attribute_default
|
|
639
|
+
return @raw_integer_column_default if defined?(@raw_integer_column_default)
|
|
388
640
|
return unless owner_class.connected? && owner_class.table_exists?
|
|
389
641
|
|
|
390
642
|
owner_class.column_defaults[attribute.to_s]
|
|
@@ -434,7 +686,7 @@ module StateMachines
|
|
|
434
686
|
|
|
435
687
|
# Creates a scope for finding records *with* a particular state or
|
|
436
688
|
# states for the attribute
|
|
437
|
-
def create_with_scope(
|
|
689
|
+
def create_with_scope(_name)
|
|
438
690
|
attr_name = attribute
|
|
439
691
|
lambda do |klass, values|
|
|
440
692
|
if values.present?
|
|
@@ -447,7 +699,7 @@ module StateMachines
|
|
|
447
699
|
|
|
448
700
|
# Creates a scope for finding records *without* a particular state or
|
|
449
701
|
# states for the attribute
|
|
450
|
-
def create_without_scope(
|
|
702
|
+
def create_without_scope(_name)
|
|
451
703
|
attr_name = attribute
|
|
452
704
|
lambda do |klass, values|
|
|
453
705
|
if values.present?
|
|
@@ -458,14 +710,13 @@ module StateMachines
|
|
|
458
710
|
end
|
|
459
711
|
end
|
|
460
712
|
|
|
461
|
-
|
|
462
713
|
# Runs a new database transaction, rolling back any changes by raising
|
|
463
714
|
# an ActiveRecord::Rollback exception if the yielded block fails
|
|
464
715
|
# (i.e. returns false).
|
|
465
716
|
def transaction(object)
|
|
466
717
|
result = nil
|
|
467
718
|
object.class.transaction do
|
|
468
|
-
raise ::ActiveRecord::Rollback unless result = yield
|
|
719
|
+
raise ::ActiveRecord::Rollback unless (result = yield)
|
|
469
720
|
end
|
|
470
721
|
result
|
|
471
722
|
end
|
|
@@ -476,7 +727,6 @@ module StateMachines
|
|
|
476
727
|
|
|
477
728
|
private
|
|
478
729
|
|
|
479
|
-
|
|
480
730
|
# Generates the results for the given scope based on one or more states to filter by
|
|
481
731
|
def run_scope(scope, machine, klass, states)
|
|
482
732
|
values = states.flatten.compact.map { |state| machine.states.fetch(state).value }
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: state_machines-activerecord
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.102.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Abdelkader Boudih
|
|
@@ -30,14 +30,14 @@ dependencies:
|
|
|
30
30
|
requirements:
|
|
31
31
|
- - ">="
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: 0.
|
|
33
|
+
version: 0.102.0
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: 0.
|
|
40
|
+
version: 0.102.0
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: appraisal
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -56,16 +56,16 @@ dependencies:
|
|
|
56
56
|
name: minitest
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements:
|
|
59
|
-
- -
|
|
59
|
+
- - '='
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: 5.
|
|
61
|
+
version: 5.27.0
|
|
62
62
|
type: :development
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
|
-
- -
|
|
66
|
+
- - '='
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: 5.
|
|
68
|
+
version: 5.27.0
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
70
|
name: minitest-reporters
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -100,14 +100,14 @@ dependencies:
|
|
|
100
100
|
requirements:
|
|
101
101
|
- - "~>"
|
|
102
102
|
- !ruby/object:Gem::Version
|
|
103
|
-
version: '1
|
|
103
|
+
version: '2.1'
|
|
104
104
|
type: :development
|
|
105
105
|
prerelease: false
|
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
107
107
|
requirements:
|
|
108
108
|
- - "~>"
|
|
109
109
|
- !ruby/object:Gem::Version
|
|
110
|
-
version: '1
|
|
110
|
+
version: '2.1'
|
|
111
111
|
description: Adds support for creating state machines for attributes on ActiveRecord
|
|
112
112
|
email:
|
|
113
113
|
- terminale@gmail.com
|
|
@@ -121,6 +121,7 @@ files:
|
|
|
121
121
|
- lib/state_machines-activerecord.rb
|
|
122
122
|
- lib/state_machines/integrations/active_record.rb
|
|
123
123
|
- lib/state_machines/integrations/active_record/locale.rb
|
|
124
|
+
- lib/state_machines/integrations/active_record/type/integer.rb
|
|
124
125
|
- lib/state_machines/integrations/active_record/version.rb
|
|
125
126
|
homepage: https://github.com/state-machines/state_machines-activerecord/
|
|
126
127
|
licenses:
|
|
@@ -141,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
141
142
|
- !ruby/object:Gem::Version
|
|
142
143
|
version: '0'
|
|
143
144
|
requirements: []
|
|
144
|
-
rubygems_version:
|
|
145
|
+
rubygems_version: 4.0.3
|
|
145
146
|
specification_version: 4
|
|
146
147
|
summary: State machines Active Record Integration
|
|
147
148
|
test_files: []
|