As of writing, no UI is provided; all operations are via service objects, background jobs, and rake tasks.
Define a materialized view
Definition is managed via the MatViews::MatViewDefinition
model. You can create definitions in Rails console, seeds, or migrations.
# create a new definition
definition = MatViews::MatViewDefinition.create!(
name: 'my_mat_view',
sql: <<-SQL.squish,
SELECT id, name, created_at
FROM users
WHERE active = true
SQL
refresh_strategy: :concurrent, # :regular (default), :concurrent (needs unique index), :swap
unique_index_columns: ['id'], # required for :concurrent and :swap strategies
dependencies: [] # optional, array of other MatViewDefinition names
)
Create the materialized view
You can create the materialized view directly via the service object or enqueue a background job or use the Rake tasks.
Direct service call
Use this for logic that needs direct control, or for scripts/migrations where background jobs aren’t suitable.
# Direct service call
result = MatViews::Services::CreateView.call(definition.id, force: true)
if result.success?
puts "Materialized view created successfully."
else
puts "Error creating materialized view: #{result.error_message}"
end
Enqueue background job
Use this in application code where you want to offload the creation to a background job.
# Enqueue background job
MatViews::Jobs::Adapter.enqueue(
MatViews::CreateViewJob,
queue: MatViews.configuration.job_queue,
args: [definition.id, true] # force: true
)
Use Rake task
You can also use the provided Rake tasks to create materialized views by name, id, or all at once.
- All tasks require confirmation unless you pass the
--yes
flag. force
flag will drop existing views before creating.- All tasks enqueue background jobs, using Job adapter and queue from configuration.
# Create by name
bundle exec rake mat_views:create_by_name\[my_mat_view,force,--yes]
# Create by id
bundle exec rake mat_views:create_by_id\[1,force,--yes]
# Create all
bundle exec rake mat_views:create_all\[force,--yes]
Refresh the materialized view
You can refresh the materialized view directly via the service object or enqueue a background job or use the Rake tasks.
Direct service call
Use this for logic that needs direct control, or for scripts/migrations where background jobs aren’t suitable. It supports two strategies: :estimated
(default) and :full
.
:estimated
uses PostgreSQL’s query planner to estimate the number of rows to refresh, which is faster for large datasets. :full
perform proper count of rows, which is more accurate but slower. In most cases, :estimated
is sufficient.
# Direct service call
result = MatViews::Services::RefreshView.call(definition.id, :estimated)
if result.success?
puts "Materialized view refreshed successfully."
else
puts "Error refreshing materialized view: #{result.error_message}"
end
Enqueue background job
Use this in application code where you want to offload the refresh to a background job. It supports two strategies: :estimated
(default) and :full
.
# Enqueue background job
MatViews::Jobs::Adapter.enqueue(
MatViews::RefreshViewJob,
queue: MatViews.configuration.job_queue,
args: [definition.id, :estimated] # or :full
)
Use Rake task
You can also use the provided Rake tasks to refresh materialized views by name, id, or all at once.
- All tasks require confirmation unless you pass the
--yes
flag. row_count_strategy
can be:estimated
(default) or:full
.- All tasks enqueue background jobs, using Job adapter and queue from configuration.
# Refresh by name
bundle exec rake mat_views:refresh_by_name\[my_mat_view,estimated,--yes]
# Refresh by id
bundle exec rake mat_views:refresh_by_id\[1,full,--yes]
# Refresh all
bundle exec rake mat_views:refresh_all\[estimated,--yes]
Delete the materialized view
You can delete the materialized view directly via the service object or enqueue a background job or use the Rake tasks.
cascade
flag will also delete dependent views.- Deleting a view does not delete its definition; you can recreate it later.
- All tasks enqueue background jobs, using Job adapter and queue from configuration.
Direct service call
Use this for logic that needs direct control, or for scripts/migrations where background jobs aren’t suitable.
# Direct service call
result = MatViews::Services::DeleteView.call(definition.id, cascade: true)
if result.success?
puts "Materialized view deleted successfully."
else
puts "Error deleting materialized view: #{result.error_message}"
end
Enqueue background job
Use this in application code where you want to offload the deletion to a background job.
# Enqueue background job
MatViews::Jobs::Adapter.enqueue(
MatViews::DeleteViewJob,
queue: MatViews.configuration.job_queue,
args: [definition.id, true] # cascade: true
)
Use Rake task
You can also use the provided Rake tasks to delete materialized views by name, id, or all at once.
- All tasks require confirmation unless you pass the
--yes
flag. cascade
flag will also delete dependent views.- All tasks enqueue background jobs, using Job adapter and queue from configuration.
# Delete by name
bundle exec rake mat_views:delete_by_name\[my_mat_view,cascade,--yes]
# Delete by id
bundle exec rake mat_views:delete_by_id\[1,cascade,--yes]
# Delete all
bundle exec rake mat_views:delete_all\[cascade,--yes]