Class: Smriti::MatViewRun

Inherits:
ApplicationRecord show all
Defined in:
app/models/smriti/mat_view_run.rb

Overview

ActiveRecord model that tracks the lifecycle of runs for materialised views.

Each record corresponds to a single attempt to mutate a materialised view from a MatViewDefinition, storing its status, timing, and any associated error or metadata.

This model provides an auditable history of view provisioning across environments, useful for telemetry, dashboards, and debugging.

Examples:

Query recent successful runs

Smriti::MatViewRun.status_success.order(created_at: :desc).limit(10)

Check if a definition has any failed runs

definition.mat_view_runs.status_failed.any?

See Also:

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from SmritiPaginate

paginate

Methods included from SmritiI18n

hint_for, human_enum_name, human_enum_options, human_name, placeholder_for

Instance Attribute Details

#operationSymbol (readonly)

Returns One of:

  • :create - initial creation of the materialised view
  • :refresh - refreshing an existing view
  • :drop - dropping the materialised view.

Returns:

  • (Symbol)

    One of:

    • :create - initial creation of the materialised view
    • :refresh - refreshing an existing view
    • :drop - dropping the materialised view


65
66
67
68
69
# File 'app/models/smriti/mat_view_run.rb', line 65

enum :operation, {
  create: 0,
  refresh: 1,
  drop: 2
}, prefix: :operation

#statusObject (readonly)

Validations

Ensures that a status is always present.



52
53
54
55
56
# File 'app/models/smriti/mat_view_run.rb', line 52

enum :status, {
  running: 0,
  success: 1,
  failed: 2
}, prefix: :status

Class Method Details

.filter_options_for_definitionArray<Array(String, Integer)>

Options for filtering by definition

Returns:

  • (Array<Array(String, Integer)>)

    array of [name, id] pairs



224
225
226
# File 'app/models/smriti/mat_view_run.rb', line 224

def filter_options_for_definition
  Smriti::MatViewDefinition.order(:name).pluck(:name, :id)
end

.filter_options_for_operationArray<Array(String, String)>

Options for filtering by operation

Returns:

  • (Array<Array(String, String)>)

    array of [label, value] pairs



217
218
219
# File 'app/models/smriti/mat_view_run.rb', line 217

def filter_options_for_operation
  order(:operation).distinct.pluck(:operation).compact.map { |operation| [human_enum_name(:operation, operation), operation] }
end

.filter_options_for_statusArray<Array(String, String)>

Options for filtering by status

Returns:

  • (Array<Array(String, String)>)

    array of [label, value] pairs



231
232
233
# File 'app/models/smriti/mat_view_run.rb', line 231

def filter_options_for_status
  order(:status).distinct.pluck(:status).compact.map { |status| [human_enum_name(:status, status), status] }
end

Instance Method Details

#create_runsActiveRecord::Relation<Smriti::MatViewRun>

Scope create runs All runs with operation: :create.

Returns:



85
# File 'app/models/smriti/mat_view_run.rb', line 85

scope :create_runs, -> { where(operation: :create) }

#drop_runsActiveRecord::Relation<Smriti::MatViewRun>

Scope drop runs All runs with operation: :drop.

Returns:



97
# File 'app/models/smriti/mat_view_run.rb', line 97

scope :drop_runs,    -> { where(operation: :drop) }

#error_messageString?

Error message if the run failed.

Extracted from meta['error']['message'] if present.

Returns:

  • (String, nil)

    Error message or nil if none.



257
258
259
# File 'app/models/smriti/mat_view_run.rb', line 257

def error_message
  meta.dig('error', 'message')
end

#filtered_by_definitionActiveRecord::Relation<Smriti::MatViewRun>

Scope filter by definition Filters by the associated definition's ID.

Parameters:

  • definition_id (Integer)

    definition ID

Returns:



197
198
199
# File 'app/models/smriti/mat_view_run.rb', line 197

scope :filtered_by_definition, lambda { |definition_id|
  where(mat_view_definition_id: definition_id)
}

#filtered_by_operationActiveRecord::Relation<Smriti::MatViewRun>

Scope filter by operation Filters by the operation attribute.

Parameters:

  • operation (String, Symbol)

    operation value

Returns:



189
# File 'app/models/smriti/mat_view_run.rb', line 189

scope :filtered_by_operation, ->(operation) { where(operation:) }

#filtered_by_statusActiveRecord::Relation<Smriti::MatViewRun>

Scope filter by status Filters by the status attribute.

Parameters:

  • status (String, Symbol)

    status value

Returns:



207
# File 'app/models/smriti/mat_view_run.rb', line 207

scope :filtered_by_status, ->(status) { where(status:) }

#mat_view_definitionSmriti::MatViewDefinition

The definition this run belongs to.



41
# File 'app/models/smriti/mat_view_run.rb', line 41

belongs_to :mat_view_definition, class_name: 'Smriti::MatViewDefinition'

#metaHash

Metadata associated with the run.

This is a JSONB column storing arbitrary structured data about the run, such as database responses, row counts, etc.

Returns:

  • (Hash)

    Parsed JSON metadata.



247
248
249
# File 'app/models/smriti/mat_view_run.rb', line 247

def meta
  self[:meta] || {}
end

#ordered_by_definitionActiveRecord::Relation<Smriti::MatViewRun>

Scope ordered by definition name Orders by the associated definition's name attribute.

Parameters:

  • dir (Symbol, String)

    :asc or :desc

Returns:



113
# File 'app/models/smriti/mat_view_run.rb', line 113

scope :ordered_by_definition, ->(dir) { left_joins(:mat_view_definition).order("mat_view_definitions.name #{dir.to_s.upcase}") }

#ordered_by_duration_msActiveRecord::Relation<Smriti::MatViewRun>

Scope ordered by duration_ms Orders by the duration_ms attribute.

Parameters:

  • dir (Symbol, String)

    :asc or :desc

Returns:



136
# File 'app/models/smriti/mat_view_run.rb', line 136

scope :ordered_by_duration_ms, ->(dir) { order("duration_ms #{dir.to_s.upcase}") }

#ordered_by_operationActiveRecord::Relation<Smriti::MatViewRun>

Scope ordered by operation Orders by the operation attribute using humanized enum labels.

Parameters:

  • dir (Symbol, String)

    :asc or :desc

Returns:



105
# File 'app/models/smriti/mat_view_run.rb', line 105

scope :ordered_by_operation, ->(dir) { ordered_by_enum(enum_values: operations, enum_name: :operation, direction: dir) }

#ordered_by_started_atActiveRecord::Relation<Smriti::MatViewRun>

Scope ordered by started_at Orders by the started_at attribute.

Parameters:

  • dir (Symbol, String)

    :asc or :desc

Returns:



121
# File 'app/models/smriti/mat_view_run.rb', line 121

scope :ordered_by_started_at, ->(dir) { order("started_at #{dir.to_s.upcase}") }

#ordered_by_statusActiveRecord::Relation<Smriti::MatViewRun>

Scope ordered by the 'status' attribute using humanized enum labels.

Parameters:

  • dir (Symbol, String)

    :asc or :desc

Returns:



128
# File 'app/models/smriti/mat_view_run.rb', line 128

scope :ordered_by_status, ->(dir) { ordered_by_enum(enum_values: statuses, enum_name: :status, direction: dir) }

#refresh_runsActiveRecord::Relation<Smriti::MatViewRun>

Scope refresh runs All runs with operation: :refresh.

Returns:



91
# File 'app/models/smriti/mat_view_run.rb', line 91

scope :refresh_runs, -> { where(operation: :refresh) }

#row_count_afterInteger?

row count after the operation, if applicable

Returns:

  • (Integer, nil)


271
272
273
# File 'app/models/smriti/mat_view_run.rb', line 271

def row_count_after
  meta.dig('response', 'row_count_after')
end

#row_count_beforeInteger?

row count before the operation, if applicable

Returns:

  • (Integer, nil)


265
266
267
# File 'app/models/smriti/mat_view_run.rb', line 265

def row_count_before
  meta.dig('response', 'row_count_before')
end

#search_by_definitionActiveRecord::Relation<Smriti::MatViewRun>

Scope search by definition name Searches by the associated definition's name attribute using ILIKE.

Parameters:

  • term (String)

    search term

Returns:



152
153
154
155
156
157
158
159
160
161
# File 'app/models/smriti/mat_view_run.rb', line 152

scope :search_by_definition, lambda { |term|
  where("    EXISTS (\n      SELECT 1\n      FROM mat_view_definitions d\n      WHERE d.id = mat_view_runs.mat_view_definition_id\n        AND d.name ILIKE :like\n    )\n  SQL\n}\n", like: "%#{term}%")

#search_by_duration_msActiveRecord::Relation<Smriti::MatViewRun>

Scope search by duration_ms Searches the duration_ms attribute by casting to text and using ILIKE. Also supports searching with localized "X milliseconds" format.

Parameters:

  • term (String)

    search term

Returns:



177
178
179
180
181
# File 'app/models/smriti/mat_view_run.rb', line 177

scope :search_by_duration_ms, lambda { |term|
  term_with_ms = I18n.t('smriti.x_miliseconds', count: term)
  where('CAST(duration_ms AS TEXT) ILIKE ?', "%#{term}%")
    .or(where('CAST(duration_ms AS TEXT) ILIKE ?', "%#{term_with_ms}%"))
}

#search_by_operationActiveRecord::Relation<Smriti::MatViewRun>

Scope search by operation Searches the operation attribute using humanized enum labels.

Parameters:

  • term (String)

    search term

Returns:



144
# File 'app/models/smriti/mat_view_run.rb', line 144

scope :search_by_operation, ->(term) { search_by_enum(enum_values: operations, enum_name: :operation, term: term) }

#search_by_statusActiveRecord::Relation<Smriti::MatViewRun>

Scope search by status Searches the status attribute using humanized enum labels.

Parameters:

  • term (String)

    search term

Returns:



169
# File 'app/models/smriti/mat_view_run.rb', line 169

scope :search_by_status, ->(term) { search_by_enum(enum_values: statuses, enum_name: :status, term: term) }