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)

Constant Summary collapse

STATUSES =
%w[pending applied rejected].freeze
STALE_AFTER =
48.hours

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 Models::EventPublishable

#publish_event

Instance Attribute Details

#engineObject (readonly)



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

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

#formatObject (readonly)



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

validates :format,  presence: true

#qualityObject (readonly)



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

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

#statusObject (readonly)



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

validates :status,  inclusion: { in: STATUSES }

Class Method Details

.pendingActiveRecord::Relation<UpscaleProposal>

A relation of UpscaleProposals that are pending. Active Record Scope

Returns:

See Also:



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

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

.staleActiveRecord::Relation<UpscaleProposal>

A relation of UpscaleProposals that are stale. Active Record Scope

Returns:

See Also:



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

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.



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

def delete_ik_asset!
  fid = ik_file_id
  return unless fid.present?

  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).



54
55
56
# File 'app/models/upscale_proposal.rb', line 54

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

#ik_pathObject



58
59
60
# File 'app/models/upscale_proposal.rb', line 58

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

#ik_urlObject



62
63
64
# File 'app/models/upscale_proposal.rb', line 62

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

#imageImage

Returns:

See Also:



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

belongs_to :image