Class: UpscaleProposal

Inherits:
ApplicationRecord show all
Defined in:
app/models/upscale_proposal.rb

Overview

Tracks an embryonic ImageKit asset that has been processed (upscaled)
but not yet confirmed by the user. Created by ImageUpscaleWorker when
propose: true is passed; promoted to a permanent Image on confirm,
or deleted immediately on reject.

The +ik_asset+ column stores the raw ImageKit upload response (same shape
as Image#asset) so that +confirm_upscale+ can reconstruct a real Image
record without a second upload.

== Schema Information

Table name: upscale_proposals
Database name: primary

id :bigint not null, primary key
engine :string not null
format :string not null
ik_asset :jsonb not null
quality :integer default(95), not null
scale_factor :integer
status :string default("pending"), not null
topaz_model :string
created_at :datetime not null
updated_at :datetime not null
image_id :bigint not null

Indexes

index_upscale_proposals_on_image_id (image_id)
index_upscale_proposals_on_status (status)

Foreign Keys

fk_rails_... (image_id => digital_assets.id) ON DELETE => cascade

Constant Summary collapse

STATUSES =

Statuses.

%w[pending applied rejected].freeze
STALE_AFTER =

Stale after.

48.hours

Constants included from Schedulable

Schedulable::SIMPLE_FORM_OPTIONS

Instance Attribute Summary collapse

Belongs to collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from ApplicationRecord

ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation

Methods included from Schedulable

config

Methods included from Models::AfterCommittable

#after_commit

Methods included from Models::EventPublishable

#publish_event

Instance Attribute Details

#engineObject (readonly)



46
# File 'app/models/upscale_proposal.rb', line 46

validates :engine,  inclusion: { in: %w[imagekit topaz] }

#formatObject (readonly)



47
# File 'app/models/upscale_proposal.rb', line 47

validates :format,  presence: true

#qualityObject (readonly)



48
# File 'app/models/upscale_proposal.rb', line 48

validates :quality, numericality: { in: 1..100 }

#statusObject (readonly)



49
# File 'app/models/upscale_proposal.rb', line 49

validates :status,  inclusion: { in: STATUSES }

Class Method Details

.pendingActiveRecord::Relation<UpscaleProposal>

A relation of UpscaleProposals that are pending. Active Record Scope

Returns:

See Also:



51
# File 'app/models/upscale_proposal.rb', line 51

scope :pending, -> { where(status: "pending") }

.staleActiveRecord::Relation<UpscaleProposal>

A relation of UpscaleProposals that are stale. Active Record Scope

Returns:

See Also:



52
# File 'app/models/upscale_proposal.rb', line 52

scope :stale,   -> { pending.where(created_at: ...STALE_AFTER.ago) }

Instance Method Details

#delete_ik_asset!Object

Delete the embryonic ImageKit asset. Silences errors so a missing/already-
deleted asset never prevents the proposal record itself from being cleaned up.



70
71
72
73
74
75
76
77
# File 'app/models/upscale_proposal.rb', line 70

def delete_ik_asset!
  fid = ik_file_id
  return if fid.blank?

  ImageKitFactory.delete_file(fid)
rescue StandardError => e
  Rails.logger.warn "[UpscaleProposal##{id}] delete_ik_asset! failed: #{e.message}"
end

#ik_file_idObject

Convenience readers for nested ik_asset fields (snake_case first, then
legacy camelCase fallback matching Image's own accessor pattern).



56
57
58
# File 'app/models/upscale_proposal.rb', line 56

def ik_file_id
  ik_asset&.dig("file_id") || ik_asset&.dig("fileId")
end

#ik_pathObject



60
61
62
# File 'app/models/upscale_proposal.rb', line 60

def ik_path
  ik_asset&.dig("file_path") || ik_asset&.dig("filePath")
end

#ik_urlObject



64
65
66
# File 'app/models/upscale_proposal.rb', line 64

def ik_url
  ik_asset&.dig("url")
end

#imageImage

Returns:

See Also:



39
# File 'app/models/upscale_proposal.rb', line 39

belongs_to :image, inverse_of: :upscale_proposals