Skip to content

Add conditional emission to emits DSL (v0.5.1) - #40

Merged
sebscholl merged 1 commit into
mainfrom
feature/conditional-event-emission
May 25, 2026
Merged

Add conditional emission to emits DSL (v0.5.1)#40
sebscholl merged 1 commit into
mainfrom
feature/conditional-event-emission

Conversation

@sebscholl

Copy link
Copy Markdown
Contributor

Summary

  • Adds if: and unless: options to the emits macro for runtime-conditional event emission
  • Removes the unused active_model_serializers dependency (was triggering a Rails 8.2 deprecation warning)
  • Bumps version to 0.5.1

Conditional emission

Services can now gate whether an event fires based on runtime state — without the event reaching the bus, building a payload, or running validation:

# if: lambda — only emit for large transfers
emits :large_transfer_event, on: :success, if: ->(result) { result.data[:transferred] > 100 }

# unless: lambda — suppress for internal transfers
emits :standard_transfer_event, on: :success, unless: ->(result) { result.data[:internal] }

# if: method reference — only for VIP accounts
emits :vip_transfer_event, on: :success, if: :vip_sender?

# Combine both — both must pass
emits :audit_transfer_event, on: :success,
  if: ->(result) { result.data[:transferred] > 50 },
  unless: :internal_transfer?

Both options accept a lambda/proc or a Symbol naming a private instance method. The condition receives the result object, giving full access to result.data, result.error, result.success?, etc.

Fully backwards compatible — emits declarations without conditions are unaffected.

The with: option is unchanged in behaviour but is now part of **options alongside if: and unless: for a uniform signature.

active_model_serializers removal

The gem was declared as a runtime dependency and required at load time, but nothing in the codebase called into its APIs. Removing it drops one runtime dependency from consuming apps and eliminates the ActiveSupport::Configurable is deprecated warning that AMS was triggering.

Full test suite (768 examples) passes without it.

Changes

File What changed
lib/servus/events/emitter.rb emits accepts **options; new emission_condition_met? and evaluate_emission_condition private methods; emit_events_for skips blocked emissions
lib/servus/testing/matchers.rb Added failure_message_when_negated to emit_event for clean not_to emit_event(...) failures
spec/servus/base_events_spec.rb 13 new tests covering all condition forms and combinations
site/features/event-bus.md New "Conditional emission" section with examples for all forms
site/testing/services.md Documents not_to emit_event pattern
lib/servus.rb / servus.gemspec / Gemfile Removed active_model_serializers
lib/servus/version.rb Bumped to 0.5.1
CHANGELOG.md 0.5.1 entry

Test plan

  • bundle exec rspec — 768 examples, 0 failures
  • bundle exec rubocop — no offenses
  • No deprecation warnings in test output

🤖 Generated with Claude Code

Adds `if:` and `unless:` options to the `emits` macro, allowing services
to gate event emission on runtime state without affecting callers or
breaking any existing declarations.

Also removes the `active_model_serializers` dependency, which was required
but never used — and was the source of an ActiveSupport::Configurable
deprecation warning targeting Rails 8.2 removal.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@sebscholl
sebscholl merged commit c3814d1 into main May 25, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant