Module: Yes::Core::Aggregate::HasReadModel

Extended by:
ActiveSupport::Concern
Included in:
Yes::Core::Aggregate
Defined in:
lib/yes/core/aggregate/has_read_model.rb

Overview

Provides read model functionality for aggregates

Examples:

Include in an aggregate

class UserAggregate < Yes::Core::Aggregate
  include Yes::Core::Concerns::HasReadModel
end

Since:

  • 0.1.0

Instance Method Summary collapse

Instance Method Details

#init_revision_from_streamBoolean

Note:

This method bypasses validations and callbacks by using update_column

Initializes the read model’s revision column with the current event stream revision

Returns:

  • (Boolean)

    True if the update was successful

Since:

  • 0.1.0



163
164
165
# File 'lib/yes/core/aggregate/has_read_model.rb', line 163

def init_revision_from_stream
  read_model.update_column(revision_column, event_revision)
end

#read_modelApplicationRecord?

Retrieves or creates a read model instance for this aggregate

Examples:

user_aggregate = UserAggregate.new(1)
user_aggregate.read_model #=> #<User id: 1>

Returns:

  • (ApplicationRecord, nil)

    The read model instance associated with this aggregate’s ID, or nil if disabled

Since:

  • 0.1.0



124
125
126
127
128
# File 'lib/yes/core/aggregate/has_read_model.rb', line 124

def read_model
  return nil unless self.class.read_model_enabled?

  @read_model ||= self.class.read_model_class.find_or_create_by(id:)
end

#rebuild_read_model(remove: true) ⇒ void

This method returns an undefined value.

Rebuilds the read model by processing all events

Parameters:

  • remove (Boolean) (defaults to: true)

    Whether to remove the read model before rebuilding

Since:

  • 0.1.0



139
140
141
# File 'lib/yes/core/aggregate/has_read_model.rb', line 139

def rebuild_read_model(remove: true)
  Yes::Core::Aggregate::ReadModelRebuilder.new(self).call(remove:)
end

#remove_read_modelObject

Removes the read model instance for this aggregate

Since:

  • 0.1.0



131
132
133
134
# File 'lib/yes/core/aggregate/has_read_model.rb', line 131

def remove_read_model
  read_model.destroy
  @read_model = nil
end

#revisionInteger?

Returns the current revision number from the read model

Returns:

  • (Integer, nil)

    The revision number stored in the read model, or -1 if read models are disabled

Since:

  • 0.1.0



154
155
156
157
158
# File 'lib/yes/core/aggregate/has_read_model.rb', line 154

def revision
  return -1 unless self.class.read_model_enabled?

  read_model.send(revision_column)
end

#revision_columnObject

Since:

  • 0.1.0



143
144
145
146
147
148
149
150
# File 'lib/yes/core/aggregate/has_read_model.rb', line 143

def revision_column
  return :revision unless self.class.read_model_enabled?

  aggregate_revision_column = "#{self.class.context.underscore}_#{self.class.aggregate.underscore}_revision"
  return aggregate_revision_column.to_sym if read_model.class.column_names.include?(aggregate_revision_column)

  :revision
end

#update_read_model(attributes) ⇒ Boolean

Updates or creates a read model with the given attributes

Parameters:

  • attributes (Hash)

    The attributes to update the read model with

Returns:

  • (Boolean)

    Returns true if the record is saved successfully

Raises:

  • (ActiveRecord::RecordInvalid)

    If the record is invalid

Since:

  • 0.1.0



111
112
113
114
115
116
# File 'lib/yes/core/aggregate/has_read_model.rb', line 111

def update_read_model(attributes)
  locale = attributes.delete(:locale) || I18n.locale
  I18n.with_locale(locale) do
    read_model.update!(attributes)
  end
end