Class: MediaAsset

Inherits:
ApplicationRecord
  • Object
show all
Includes:
Discard::Model, PgSearch::Model, Ransackable
Defined in:
lib/generators/ruby_cms/templates/models/media_asset.rb

Overview

A media library asset (image, video, document, or other binary).

The actual binary lives in Active Storage (+file+); the row captures metadata (kind, mime type, dimensions, folder, tags, usage count, etc.) so the index can render quickly without hitting the blob service for every record.

Constant Summary collapse

KINDS =
%w[image video doc other].freeze
TONES =
%w[coral purple blue sand].freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.folder_countsObject

{ "general" => 5, "events" => 2, ..., "all" => total }. Memoised on Current so a single request only runs the GROUP BY once.



70
71
72
73
74
75
76
77
78
# File 'lib/generators/ruby_cms/templates/models/media_asset.rb', line 70

def self.folder_counts
  cached = Current.respond_to?(:media_folder_counts) && Current.media_folder_counts
  return cached if cached

  computed = group(:folder).count
  computed["all"] = computed.values.sum
  Current.media_folder_counts = computed if Current.respond_to?(:media_folder_counts=)
  computed
end

.kind_from_mime(mime) ⇒ Object

Infer kind ("image"|"video"|"doc"|"other") from a mime type string.



46
47
48
49
50
51
52
53
54
55
56
# File 'lib/generators/ruby_cms/templates/models/media_asset.rb', line 46

def self.kind_from_mime(mime)
  case mime.to_s
  when %r{\Aimage/}        then "image"
  when %r{\Avideo/}        then "video"
  when "application/pdf",
       %r{\Aapplication/(msword|vnd\.openxmlformats|vnd\.oasis)},
       "text/plain",
       "text/csv" then "doc"
  else "other"
  end
end

.kindsObject



36
37
38
# File 'lib/generators/ruby_cms/templates/models/media_asset.rb', line 36

def self.kinds
  KINDS
end

.search(term) ⇒ Object

Full-text on name/folder via pg_search, plus tag containment fallback so exact tag matches still hit even when tsearch tokenises them out.



60
61
62
63
64
65
66
# File 'lib/generators/ruby_cms/templates/models/media_asset.rb', line 60

def self.search(term)
  return all if term.blank?

  fulltext_ids = search_by_term(term).select(:id)
  tag_match = where("tags @> ?", [term].to_json)
  where(id: fulltext_ids).or(tag_match)
end

.tone_for(name) ⇒ Object

Hash a name into one of TONES so the same name always picks the same tone.



41
42
43
# File 'lib/generators/ruby_cms/templates/models/media_asset.rb', line 41

def self.tone_for(name)
  TONES[name.to_s.sum % TONES.size]
end

Instance Method Details

#cdn_urlObject

Stringified URL to the attached file, or nil when nothing is attached. Falls back to a path-only blob URL when default_url_options is unset (e.g. in console / runners).



83
84
85
86
87
88
89
# File 'lib/generators/ruby_cms/templates/models/media_asset.rb', line 83

def cdn_url
  return nil unless file.attached?

  Rails.application.routes.url_helpers.url_for(file)
rescue ArgumentError
  Rails.application.routes.url_helpers.rails_blob_path(file, only_path: true)
end