Rails Execution
Rails Execution is an Engine to manage the Rails scripts for migration, cleanup, and fixing the bad data without deployment.
- Supported the Syntax checker
- Supported the Execution logs
- Supported the Reviewing process
- Supported the Attachment files
- Supported the Comments communication
- Supported the Activities tracking
Installation
Add the following line to your Gemfile:
gem 'rails_execution'
Then run bundle install
Getting started
How to setup
You need to run the generator:
$ rails g rails_execution:install
And you can change the config in config/initializers/rails_execution.rb
Default is Solo Mode
, without the Reviewing process.
Enable the Reviewing process
The first step is to disable the Solo Mode
config.solo_mode = false
And then uncomment the configures of the owner
and reviewers
config.owner_model = 'User'
config.owner_method = :current_user
config.owner_name_method = :name
config.owner_avatar = ->(owner) { owner.avatar.url }
config.reviewers = -> do
User.where(is_admin: true).map do |user|
{
name: user.name,
id: user.id,
type: 'User',
avatar_url: user.avatar.url,
}
end
end
Enable the Attachment files
Run the generator to add the FileUploader and FileReader
$ rails g rails_execution:file_upload
And then uncomment the file upload
config.file_upload = true
config.file_uploader = ::RailsExecution::FileUploader
config.file_reader = ::RailsExecution::FileReader
To limit the File types. Default: .png
, .gif
, .jpg
, .jpeg
, .pdf
, .csv
You can modify the limitation like this
config.acceptable_file_types = {
'.jpeg': 'image/jpeg',
'.pdf': 'application/pdf',
'.csv': ['text/csv', 'text/plain'],
}
Control the Permissions
For example with Pundit authorization.
config.task_creatable = lambda do |user|
YourPolicy.new(user).creatable?
end
config.task_editable = lambda do |task, user|
YourPolicy.new(user, task).editable?
end
config.task_closable = lambda do |task, user|
YourPolicy.new(user, task).closable?
end
config.task_approvable = lambda do |task, user|
YourPolicy.new(user, task).approvable?
end
config.task_executable = lambda do |task, user|
YourPolicy.new(user, task).executable?
end
Setup the Logger
To storage the logfile
config.logging = lambda do |file, task|
LoggerModel.create!(task: task, file: file)
end
And list the logfiles on Task page
config.logging_files = lambda do |task|
LoggerModel.where(task: task).map do |log|
log.file.expiring_url(30.minutes.to_i)
end
end
In case you want to render logs more fancy in the view, you need to return list of file and created_at
config.logging_files = lambda do |task|
LoggerModel.where(task: task).map do |log|
[log.file.expiring_url(30.minutes.to_i), log.created_at]
end
end
Enable Task Schedule
Depend on which gem you use to schedule a job you need to modify the block inside lambda function to invoke ::RailsExecution::Services::TaskScheduler.call(task_id)
In this case Sidekiq
is used with option delay_until
and set to run at scheduled_at
config.task_schedulable = true
config.task_scheduler = ->(scheduled_at, task_id) { ::RailsExecution::Services::TaskScheduler.delay_until(scheduled_at).call(task_id) }
config.scheduled_task_remover = ->(task_id) { Sidekiq::ScheduledSet.new.find_job(jid).delete }
Enable Task Background
Depend on which gem you use to run background job you need to modify the block inside lambda function to invoke ::RailsExecution::Services::BackgroundExecution.call(task_id)
config.task_background = true
config.task_background_executor = ->(task_id) { ::RailsExecution::Services::BackgroundExecution.delay.call(task_id) }
Others
To change the Per page of the tasks list.
Default value: 20
config.per_page = 10
Pro-tips
Logging
- In editor, you can call the
log
method withmessage
to log the message to logfile
Example:
log('Read upload file successful')
Output:
==================== Wed, 22 Mar 2023 00:31:48
Read upload file successful
And within the label liked it
log('Success', 'Read upload file')
Output:
==================== Success
Read upload file
Show object Information
- If you want to show the object information in loop or in the step by step, you can use the
info
method to show Model name and id.ruby ids = [1, 2] Product.where(id: ids).each do |product| info(product) # Your code to process the product end
Output:
==================== Product#1
==================== Product#2
Force to stop the process
If you want to add the message to log and STOP process, you can use the error!
method
Example:
error!('Bad-data', 'Unmatched value!') if var_x != var_y
Output:
==================== Bad-data
Unmatched value!
==================== Rolling back...
OR you can use the stop!
method to Stop the process
Example:
stop!
or
stop!('bad-data')