module JSONAPI::ResourceActions::CrudHelpers

def apply_sti_type(klass, params)

def apply_sti_type(klass, params)
  return unless sti_base_with_type_column?(klass)
  params["type"] = klass.name
end

def clean_params(hash, attachments)

def clean_params(hash, attachments)
  attachments.each_key { |k| hash.delete(k.to_s) }
  hash.delete("type")
  hash.delete(:type)
end

def determine_sti_class

def determine_sti_class
  JSONAPI::ResourceLoader.find(jsonapi_type || resource_type).model_class
rescue JSONAPI::ResourceLoader::MissingResourceClass
  model_class
end

def determine_sti_resource_class

def determine_sti_resource_class
  JSONAPI::ResourceLoader.find(jsonapi_type || resource_type)
rescue JSONAPI::ResourceLoader::MissingResourceClass
  @resource_class
end

def prepare_create_params(sti_class)

def prepare_create_params(sti_class)
  hash = deserialize_params(:create, model_class: sti_class)
  attachments = extract_active_storage_params_from_hash(hash, sti_class)
  clean_params(hash, attachments)
  apply_sti_type(sti_class, hash)
  [hash, attachments]
end

def prepare_create_params_from_data(sti_class, data)

def prepare_create_params_from_data(sti_class, data)
  hash = deserialize_params(:create, model_class: sti_class, data:)
  attachments = extract_active_storage_params_from_hash(hash, sti_class)
  clean_params(hash, attachments)
  apply_sti_type(sti_class, hash)
  [hash, attachments]
end

def prepare_update_params

def prepare_update_params
  hash = deserialize_params(:update)
  attachments = extract_active_storage_params_from_hash(hash, model_class)
  clean_params(hash, attachments)
  [hash, attachments]
end

def render_create_error(error)

def render_create_error(error)
  if error.message.match?(/invalid.*subtype/i)
    render_invalid_subtype_error(error)
  else
    render_invalid_relationship_error(error)
  end
end

def render_signed_id_error(error)

def render_signed_id_error(error)
  render_jsonapi_error(
    status: 400,
    title: "Invalid Signed ID",
    detail: "Invalid signed blob ID provided: #{error.message}",
  )
end

def save_created(resource)

def save_created(resource)
  return render_validation_errors(resource) unless resource.save
  emit_resource_event(:created, resource)
  render json: serialize_resource(resource), status: :created, location: resource_url(resource)
end

def save_created_with_sidepost(resource, sideposted_records)

def save_created_with_sidepost(resource, sideposted_records)
  raise JSONAPI::Sideposting::PrimaryValidationError, resource unless resource.save
  emit_resource_event(:created, resource)
  render json: serialize_resource_with_sidepost(resource, sideposted_records),
         status: :created,
         location: resource_url(resource)
end

def save_updated(params_hash, attachments)

def save_updated(params_hash, attachments)
  return render_validation_errors(@resource) unless @resource.update(params_hash)
  attach_active_storage_files(@resource, attachments, resource_class: @resource_class)
  emit_resource_event(:updated, @resource)
  render json: serialize_resource(@resource), status: :ok
end

def sti_base_with_type_column?(klass)

def sti_base_with_type_column?(klass)
  klass.respond_to?(:base_class) && klass.base_class == klass && klass.column_names.include?("type")
end