Module: Spree::Publishable
- Extended by:
- ActiveSupport::Concern
- Included in:
- Base, UserMethods
- Defined in:
- app/models/concerns/spree/publishable.rb
Overview
Concern for models that publish events.
This concern is included in Spree::Base, so all Spree models can emit events. Event payloads are generated using V3 API serializers resolved by convention: Spree::Order → Spree::Api::V3::OrderSerializer.
Models without a V3 serializer get a minimal fallback payload:
{ id: prefixed_id, created_at: ..., updated_at: ... }
STI models (e.g., Spree::Exports::Products) can override event_serializer_class to point to the parent serializer.
Instance Method Summary collapse
-
#event_context ⇒ Hash
Context passed to the event serializer.
-
#event_payload ⇒ Hash
Get the payload for events.
-
#event_prefix ⇒ String
Get the event prefix for this instance.
-
#event_serializer_class ⇒ Class?
Find the event serializer class for this model.
-
#publish_event(event_name, payload = nil, metadata = {}) ⇒ Spree::Event
Publish an event with this model's data.
-
#touch(*names, time: nil) ⇒ Object
A bare
touch(variant → product, price → variant, asset → variants) writes no attribute changes — the resulting update event would carry nothing subscribers haven't already been told.
Instance Method Details
#event_context ⇒ Hash
Context passed to the event serializer
209 210 211 212 213 214 215 |
# File 'app/models/concerns/spree/publishable.rb', line 209 def event_context { event_name: @_current_event_name, store_id: Spree::Current.store&.id, triggered_at: Time.current } end |
#event_payload ⇒ Hash
Get the payload for events
Uses the V3 serializer resolved by convention. Falls back to a minimal payload if no serializer is found.
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'app/models/concerns/spree/publishable.rb', line 163 def event_payload serializer = event_serializer_class unless serializer return { id: respond_to?(:prefixed_id) ? prefixed_id : id, created_at: created_at&.iso8601, updated_at: updated_at&.iso8601 } end # Use as_json to ensure all values are JSON-safe primitives. # Alba's to_h can return raw Ruby objects (e.g., Spree::Money) which # ActiveJob cannot serialize for async event subscribers. serializer.new(self, params: event_serializer_params).to_h.as_json end |
#event_prefix ⇒ String
Get the event prefix for this instance
220 221 222 |
# File 'app/models/concerns/spree/publishable.rb', line 220 def event_prefix self.class.event_prefix end |
#event_serializer_class ⇒ Class?
Find the event serializer class for this model
Looks for Spree::Api::V3::ModelNameSerializer by convention. Walks up the class hierarchy to support STI models.
Models can override this method to specify a custom serializer, which is useful for STI models like Export, Import, Report.
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'app/models/concerns/spree/publishable.rb', line 189 def event_serializer_class return nil unless self.class.name klass = self.class while klass && klass != Object && klass != BasicObject class_name = klass.name&.demodulize if class_name.present? && class_name != 'Base' serializer = "Spree::Api::V3::#{class_name}Serializer".safe_constantize return serializer if serializer end klass = klass.superclass end nil end |
#publish_event(event_name, payload = nil, metadata = {}) ⇒ Spree::Event
Publish an event with this model's data
147 148 149 150 151 152 153 154 155 |
# File 'app/models/concerns/spree/publishable.rb', line 147 def publish_event(event_name, payload = nil, = {}) return unless Spree::Events.enabled? @_current_event_name = event_name payload ||= event_payload Spree::Events.publish(event_name, payload, ) ensure @_current_event_name = nil end |
#touch(*names, time: nil) ⇒ Object
A bare touch (variant → product, price → variant, asset → variants)
writes no attribute changes — the resulting update event would carry
nothing subscribers haven't already been told. Track it here so the
commit callback can tell a touch-only commit from a real update;
saved_changes can't (a touch replays the previous save's changeset).
51 52 53 54 |
# File 'app/models/concerns/spree/publishable.rb', line 51 def touch(*names, time: nil) @_spree_touched_for_events = true super end |