0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-06 13:08:40 +08:00
discourse/plugins/automation/app/services/discourse_automation/create.rb
Régis Hanol e70137509e
DEV: Refactor automation Update service per PR #36458 feedback (#36771)
Addresses code review feedback to improve the automation Update service
by following Discourse service best practices and extracting complex
logic into a dedicated action class.

Changes:
- Extract logging logic to
`DiscourseAutomation::Action::LogAutomationUpdate` action class,
removing utility methods from the service (per service guidelines that
discourage utility methods in services)
- Use `model` step for `previous_state` instead of regular step
- Simplify `capture_previous_state` using `slice` and `merge`
- Pass `previous_state` as explicit parameter to `log_action`
- Remove unused `params` from `apply_forced_triggerable`
- Simplify attributes building with
`symbolize_keys.slice().compact_blank`
- Simplify save logic: `save!(validate: context[:clear_trigger].blank?)`
- Use `index_with` for building change hashes in action class
- Use `have_attributes` matcher in request specs
- Simplify boolean checks with `value.in?([true, false])`

References:
- PR feedback: https://github.com/discourse/discourse/pull/36458
- Service objects guide:
https://meta.discourse.org/t/using-service-objects-in-discourse/333641
2025-12-18 18:16:03 +01:00

60 lines
1.3 KiB
Ruby
Vendored

# frozen_string_literal: true
class DiscourseAutomation::Create
include Service::Base
# @!method self.call(guardian:, params:)
# @param [Guardian] guardian
# @param [Hash] params
# @option params [String] :script
# @option params [String] :trigger
# @return [Service::Base::Context]
policy :can_create_automation
params do
attribute :script, :string
attribute :trigger, :string
validates :script, presence: true
end
model :automation, :instantiate_automation
transaction do
step :apply_forced_triggerable
step :save_automation
step :log_action
end
private
def can_create_automation(guardian:)
guardian.is_admin?
end
def instantiate_automation(params:, guardian:)
DiscourseAutomation::Automation.new(
script: params.script,
trigger: params.trigger,
last_updated_by_id: guardian.user.id,
)
end
def apply_forced_triggerable(automation:)
if automation.scriptable&.forced_triggerable
automation.trigger = automation.scriptable.forced_triggerable[:triggerable].to_s
end
end
def save_automation(automation:)
automation.save!
end
def log_action(automation:, guardian:)
StaffActionLogger.new(guardian.user).log_custom(
"create_automation",
automation.slice(:id, :name, :script, :trigger).compact_blank,
)
end
end