You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: update_service.rb
    path of file: ./repos/gitlabhq/app/services/feature_flags
    
    the code of the file until where you have to start completion: # frozen_string_literal: true

module FeatureFlags
  class UpdateService < FeatureFlags::BaseService
    AUDITABLE_STRATEGY_ATTRIBUTES_HUMAN_NAMES = {
      'scopes' => 'environment scopes',
      'parameters' => 'parameters'
    }.freeze

    def success(**args)
      execute_hooks_after_commit(args[:feature_flag])
      super
    end

    def execute(feature_flag)
      return error('Access Denied', 403) unless can_update?(feature_flag)
   
    
    def updated_strategy_message(strategy)
      changes = strategy.changes.slice(*AUDITABLE_STRATEGY_ATTRIBUTES_HUMAN_NAMES.keys)
      return if changes.empty?

      message = "Updated strategy #{strategy.name} "
      message += changes.map do |attribute_name, change|
        name = AUDITABLE_STRATEGY_ATTRIBUTES_HUMAN_NAMES[attribute_name]
        "#{name} from #{change.first} to #{change.second}"
      end.join(' ')

      message + '.'
    end

    def can_update?(feature_flag)
      Ability.allowed?(current_user, :update_feature_flag, feature_flag)
    end

    def user_list_ids(params)
      params.fetch(:strategies_attributes, [])
        .select { |s| s[:user_list_id].present? }
        .map { |s| s[:user_list_id] }
    end

    def valid_user_list_ids?(feature_flag, user_list_ids)
      user_list_ids.empty? || ::Operations::FeatureFlags::UserList.belongs_to?(feature_flag.project_id, user_list_ids)
    end
  end