Help me een Ruby-script te maken dat een toestandsmachine implementeert voor een specifiek proces.
description
Door een toestandsmachine te implementeren, kun je het beheer van complexe processen stroomlijnen, je code schoner maken en gemakkelijker onderhouden. Deze aanpak bevordert een betere organisatie en kan de algehele robuustheid van je toepassing verbeteren.
prompt
try_prompt
Ik heb hulp nodig bij het schrijven van een Ruby-script dat een toestandsmachine implementeert voor het volgende proces: {{proces_beschrijving}}. Geef de verschillende toestanden, o ... more
generate_helper
...
tags
ai_answers
provider: openai
model: gpt-4.1-nano
Hier is een voorbeeld van een Ruby-script dat een toestandsmachine implementeert voor het verwerken van klantbestellingen. Ik heb gebruik gemaakt van een eenvoudige en onderhoudbare aanpak, volgens beste praktijken, met duidelijke toestanden, overgangen en gebeurtenissen.
### Stap 1: Definieer de toestanden en gebeurtenissen
De toestanden kunnen zijn:
- :created (bestelling aangemaakt)
- :paid (betaling voltooid)
- :packed (verpakking voltooid)
- :shipped (verzending voltooid)
- :delivered (afgeleverd)
- :cancelled (geannuleerd)
Gebeurtenissen die overgangen triggeren:
- :pay (betaling ontvangen)
- :pack (verpakking gestart)
- :ship (verzending)
- :deliver (levering)
- :cancel (annulering)
### Stap 2: Implementatie in Ruby
```ruby
# Definieer een klasse voor de Bestelling met toestandsmachine
class Bestelling
attr_reader :toestand
# Definieer alle mogelijke toestanden
TOESTANDEN = [
:created,
:paid,
:packed,
:shipped,
:delivered,
:cancelled
]
def initialize
@toestand = :created
end
# Methode om de huidige toestand te tonen
def status
"De bestelling bevindt zich in de toestand: #{@toestand}"
end
# Gebeurtenissen die toestanden veranderen
def betaal
transition(:paid) if @toestand == :created
end
def verpak
transition(:packed) if @toestand == :paid
end
def verstuur
transition(:shipped) if @toestand == :packed
end
def lever
transition(:delivered) if @toestand == :shipped
end
def annuleer
# Bestelling kan alleen worden geannuleerd als niet geleverd
transition(:cancelled) if @toestand != :delivered
end
private
def transition(nieuwe_toestand)
puts "Overgang van #{@toestand} naar #{nieuwe_toestand}"
@toestand = nieuwe_toestand
end
end
# Voorbeeldgebruik
bestelling = Bestelling.new
puts bestelling.status
bestelling.betaal
puts bestelling.status
bestelling.verpak
puts bestelling.status
bestelling.verstuur
puts bestelling.status
bestelling.lever
puts bestelling.status
# Optioneel: annuleren
# bestelling.annuleer
# puts bestelling.status
```
### Uitleg:
- De klasse `Bestelling` bevat een toestand (`@toestand`) en methoden die gebeurtenissen representeren.
- Elke gebeurtenis controleert of de overgang geldig is vanuit de huidige toestand.
- De `transition`-private methode voert de overgang uit en geeft een bericht.
- Dit ontwerp is onderhoudbaar, want je kunt eenvoudig nieuwe toestanden en gebeurtenissen toevoegen.
### Uitbreidingen:
- Voeg validaties toe voor ongeldige overgangen.
- Gebruik een state machine gemoduleerde bibliotheek zoals `state_machine` voor complexere logica.
- Voeg logging toe voor betere traceerbaarheid.
Als je verdere hulp nodig hebt of het script wilt uitbreiden, laat het gerust weten!
provider: deepseek
model: deepseek-chat
Ik zal je helpen een duidelijke en onderhoudbare toestandsmachine in Ruby te schrijven voor het verwerken van klantbestellingen. Hier is een implementatie met de `aasm` gem, een van de populairste state machine libraries voor Ruby.
```ruby
# Voeg toe aan je Gemfile: gem 'aasm'
require 'aasm'
class Order
include AASM
# Toestanden
aasm do
state :ontvangen, initial: true
state :gevalideerd
state :betaald
state :verzameld
state :verzonden
state :afgeleverd
state :geannuleerd
state :teruggestuurd
# Gebeurtenissen en overgangen
event :valideren do
transitions from: :ontvangen, to: :gevalideerd
end
event :betalen do
transitions from: :gevalideerd, to: :betaald
end
event :verzamelen do
transitions from: :betaald, to: :verzameld
end
event :verzenden do
transitions from: :verzameld, to: :verzonden
end
event :afleveren do
transitions from: :verzonden, to: :afgeleverd
end
event :annuleren do
transitions from: [:ontvangen, :gevalideerd, :betaald], to: :geannuleerd
end
event :retourneren do
transitions from: :afgeleverd, to: :teruggestuurd
end
end
# Optionele callbacks voor aanvullende logica
def after_valideren
puts "Bestelling gevalideerd: #{self.id}"
# Voer validatielogica uit
end
def after_betalen
puts "Betaling ontvangen voor bestelling: #{self.id}"
# Verwerk betaling
end
def after_verzamelen
puts "Artikelen verzameld voor bestelling: #{self.id}"
# Update voorraad
end
def after_verzenden
puts "Bestelling verzonden: #{self.id}"
# Genereer trackingnummer
end
def after_afleveren
puts "Bestelling afgeleverd: #{self.id}"
# Stuur bevestiging naar klant
end
def after_annuleren
puts "Bestelling geannuleerd: #{self.id}"
# Stuur annuleringsbevestiging
end
def after_retourneren
puts "Bestelling teruggestuurd: #{self.id}"
# Verwerk retour
end
end
# Gebruiksvoorbeeld:
bestelling = Order.new
puts "Huidige toestand: #{bestelling.aasm.current_state}" # => :ontvangen
# Doorloop het proces
bestelling.valideren!
puts "Toestand na valideren: #{bestelling.aasm.current_state}" # => :gevalideerd
bestelling.betalen!
puts "Toestand na betalen: #{bestelling.aasm.current_state}" # => :betaald
bestelling.verzamelen!
puts "Toestand na verzamelen: #{bestelling.aasm.current_state}" # => :verzameld
bestelling.verzenden!
puts "Toestand na verzenden: #{bestelling.aasm.current_state}" # => :verzonden
bestelling.afleveren!
puts "Toestand na afleveren: #{bestelling.aasm.current_state}" # => :afgeleverd
# Controleer of een overgang mogelijk is
puts "Kan annuleren? #{bestelling.may_annuleren?}" # => false (niet in juiste toestand)
# Alternatieve implementatie zonder callbacks (eenvoudiger)
class SimpleOrder
include AASM
aasm do
state :wachtend_op_bevestiging, initial: true
state :bevestigd
state :in_verwerking
state :verzonden
state :afgerond
state :geannuleerd
event :bevestigen do
transitions from: :wachtend_op_bevestiging, to: :bevestigd
end
event :start_verwerking do
transitions from: :bevestigd, to: :in_verwerking
end
event :verzend do
transitions from: :in_verwerking, to: :verzonden
end
event :voltooien do
transitions from: :verzonden, to: :afgerond
end
event :annuleer do
transitions from: [:wachtend_op_bevestiging, :bevestigd], to: :geannuleerd
end
end
end
```
## Toestandsdiagram samenvatting:
```
Ontvangen → [valideren] → Gevalideerd → [betalen] → Betaald → [verzamelen] → Verzameld
↓ ↓ ↓
[annuleren] [annuleren] [annuleren]
↓ ↓ ↓
Geannuleerd Geannuleerd Geannuleerd
Verzameld → [verzenden] → Verzonden → [afleveren] → Afgeleverd → [retourneren] → Teruggestuurd
```
## Beste praktijken geïmplementeerd:
1. **Duidelijke toestanden**: Elke toestand vertegenwoordigt een betekenisvolle fase
2. **Expliciete overgangen**: Gebeurtenissen triggeren specifieke toestandswijzigingen
3. **Foutafhandeling**: AASM voorkomt ongeldige toestandsovergangen
4. **Callbacks**: Voor aanvullende bedrijfslogica bij elke overgang
5. **Testbaar**: Eenvoudig te testen met `may_?` methoden
## Installatie:
```bash
gem install aasm
```
Of voeg toe aan je Gemfile:
```ruby
gem 'aasm'
```
Deze implementatie is schaalbaar, onderhoudbaar en volgt Ruby-best practices voor toestandsmachines.

