0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-08 17:53:55 +08:00
discourse/plugins/automation/app/controllers/discourse_automation/admin_automations_controller.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

84 lines
2.6 KiB
Ruby
Vendored

# frozen_string_literal: true
module DiscourseAutomation
class AdminAutomationsController < ::Admin::AdminController
requires_plugin PLUGIN_NAME
def index
automations =
DiscourseAutomation::Automation
.strict_loading
.includes(:fields, :pending_automations, :last_updated_by)
.order(:name)
.limit(500)
.all
serializer =
ActiveModel::ArraySerializer.new(
automations,
each_serializer: DiscourseAutomation::AutomationSerializer,
root: "automations",
scope: {
stats: DiscourseAutomation::Stat.fetch_period_summaries,
},
).as_json
render_json_dump(serializer)
end
def show
automation =
DiscourseAutomation::Automation.includes(
:fields,
:pending_automations,
:last_updated_by,
).find(params[:id])
render_serialized_automation(automation)
end
def create
DiscourseAutomation::Create.call(
params: params.require(:automation).to_unsafe_h,
guardian:,
) do
on_success { |automation:| render_serialized_automation(automation) }
on_failed_policy(:can_create_automation) { raise Discourse::InvalidAccess }
on_failed_contract do |contract|
render json: failed_json.merge(errors: contract.errors.full_messages),
status: :bad_request
end
on_failure { raise Discourse::InvalidParameters }
end
end
def update
DiscourseAutomation::Update.call(
params: params.require(:automation).to_unsafe_h.merge(automation_id: params[:id]),
guardian:,
) do
on_success { |automation:| render_serialized_automation(automation) }
on_model_not_found(:automation) { raise Discourse::NotFound }
on_failed_policy(:can_update_automation) { raise Discourse::InvalidAccess }
on_failed_contract do |contract|
render json: failed_json.merge(errors: contract.errors.full_messages),
status: :bad_request
end
on_failure { raise Discourse::InvalidParameters }
end
end
def destroy
DiscourseAutomation::Destroy.call(service_params) do
on_success { render(json: success_json) }
on_model_not_found(:automation) { raise Discourse::NotFound }
on_failed_policy(:can_destroy_automation) { raise Discourse::InvalidAccess }
end
end
private
def render_serialized_automation(automation)
serializer =
DiscourseAutomation::AutomationSerializer.new(automation, root: "automation").as_json
render_json_dump(serializer)
end
end
end