Module: ActiveStorageDashboard::ApplicationHelper

Defined in:
app/helpers/active_storage_dashboard/application_helper.rb

Instance Method Summary collapse

Instance Method Details

#active_storage_dashboardObject

Ensure we’re properly using the engine routes



240
241
242
# File 'app/helpers/active_storage_dashboard/application_helper.rb', line 240

def active_storage_dashboard
  ActiveStorageDashboard::Engine.routes.url_helpers
end

#attachment_path(attachment) ⇒ Object



265
266
267
# File 'app/helpers/active_storage_dashboard/application_helper.rb', line 265

def attachment_path(attachment)
  active_storage_dashboard.attachment_path(attachment)
end

#attachment_preview(attachment) ⇒ Object

Generate preview HTML for an attachment



168
169
170
171
172
# File 'app/helpers/active_storage_dashboard/application_helper.rb', line 168

def attachment_preview(attachment)
  return "" unless attachment&.blob&.present?
  
  blob_preview(attachment.blob)
end

#attachments_pathObject



273
274
275
# File 'app/helpers/active_storage_dashboard/application_helper.rb', line 273

def attachments_path
  active_storage_dashboard.attachments_path
end

#blob_path(blob) ⇒ Object



269
270
271
# File 'app/helpers/active_storage_dashboard/application_helper.rb', line 269

def blob_path(blob)
  active_storage_dashboard.blob_path(blob)
end

#blob_preview(blob) ⇒ Object

Generate preview HTML for a blob



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'app/helpers/active_storage_dashboard/application_helper.rb', line 131

def blob_preview(blob)
  return "" unless blob.present?
  
  content_type = blob.content_type
  
  if content_type&.start_with?('image/')
    url = Rails.application.routes.url_helpers.rails_blob_url(blob, disposition: "inline", only_path: true)
    return image_tag(url, alt: blob.filename)
  elsif defined?(ActiveStorage::Blob.new.preview) && 
        blob.respond_to?(:previewable?) && 
        blob.previewable?
    # This will work in Rails 6+ with proper preview handlers configured
    begin
      url = Rails.application.routes.url_helpers.rails_blob_url(
        blob.preview(resize: "300x300").processed.image, 
        disposition: "inline", 
        only_path: true
      )
      return image_tag(url, alt: blob.filename, class: "preview-image")
    rescue => e
      # Fallback if preview fails for any reason
      Rails.logger.error("Preview generation failed: #{e.message}")
      return (:div, "Preview not available", class: "preview-error")
    end
  end
  
  return (:div, "No preview available", class: "no-preview")
end

#blobs_pathObject



277
278
279
# File 'app/helpers/active_storage_dashboard/application_helper.rb', line 277

def blobs_path
  active_storage_dashboard.blobs_path
end

#download_attachment_path(attachment, options = {}) ⇒ Object

Fix URL generation by explicitly using the engine routes



245
246
247
248
249
250
251
252
253
# File 'app/helpers/active_storage_dashboard/application_helper.rb', line 245

def download_attachment_path(attachment, options = {})
  if options[:disposition].present?
    # For paths with parameters, we need to construct the URL manually
    disposition = options[:disposition]
    active_storage_dashboard.download_attachment_path(attachment, disposition: disposition)
  else
    active_storage_dashboard.download_attachment_path(attachment)
  end
end

#download_blob_path(blob, options = {}) ⇒ Object



255
256
257
258
259
260
261
262
263
# File 'app/helpers/active_storage_dashboard/application_helper.rb', line 255

def download_blob_path(blob, options = {})
  if options[:disposition].present?
    # For paths with parameters, we need to construct the URL manually
    disposition = options[:disposition]
    active_storage_dashboard.download_blob_path(blob, disposition: disposition)
  else
    active_storage_dashboard.download_blob_path(blob)
  end
end

#download_blob_url(blob) ⇒ Object

Helper to generate a download URL for a blob



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'app/helpers/active_storage_dashboard/application_helper.rb', line 175

def download_blob_url(blob)
  begin
    # Try simple direct download URL first using the blob's service URL
    # This is often the most reliable method
    if blob.respond_to?(:service_url)
      return blob.service_url(disposition: "attachment", filename: blob.filename.to_s)
    end
    
    # If we're in a Rails 6.1+ app, use the direct representation URL
    if Rails.gem_version >= Gem::Version.new('6.1') &&
       blob.respond_to?(:representation) &&
       Rails.application.routes.url_helpers.respond_to?(:rails_blob_representation_url)
      
      # Force a download by using the blob directly
      return Rails.application.routes.url_helpers.rails_blob_url(blob, disposition: "attachment")
    end
    
    # For Rails 6.0, use standard blob URL approach
    if Rails.application.routes.url_helpers.respond_to?(:rails_blob_url)
      host_options = {}
      
      # Make sure we have a host set for URL generation
      if defined?(request) && request.present?
        host_options[:host] = request.host
        host_options[:port] = request.port if request.port != 80 && request.port != 443
        host_options[:protocol] = request.protocol.sub('://', '')
      elsif Rails.application.config.action_controller.default_url_options[:host].present?
        host_options = Rails.application.config.action_controller.default_url_options
      else
        # Fallback to localhost for development
        host_options[:host] = 'localhost'
        host_options[:port] = 3000
        host_options[:protocol] = 'http'
      end
      
      # Ensure disposition is set for attachment download
      return Rails.application.routes.url_helpers.rails_blob_url(blob, **host_options, disposition: "attachment")
    end
    
    # For Rails 5.2
    if Rails.application.routes.url_helpers.respond_to?(:rails_service_blob_url)
      host_options = {}
      if defined?(request) && request.present?
        host_options[:host] = request.host
        host_options[:port] = request.port if request.port != 80 && request.port != 443
        host_options[:protocol] = request.protocol.sub('://', '')
      end
      return Rails.application.routes.url_helpers.rails_service_blob_url(blob.key, **host_options, disposition: "attachment")
    end
    
    # If all else fails, use the direct download path (for development)
    if Rails.application.routes.url_helpers.respond_to?(:rails_blob_path)
      return Rails.application.routes.url_helpers.rails_blob_path(blob, disposition: "attachment")
    end
    
    Rails.logger.error("Could not determine download URL for blob #{blob.id}")
    return "#"
  rescue => e
    Rails.logger.error("Error generating download URL: #{e.message}")
    Rails.logger.error(e.backtrace.join("\n"))
    return "#"
  end
end

#format_bytes(bytes) ⇒ Object



98
99
100
101
102
103
104
105
106
107
# File 'app/helpers/active_storage_dashboard/application_helper.rb', line 98

def format_bytes(bytes)
  return '0 B' if bytes.nil? || bytes == 0
  
  units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
  exponent = (Math.log(bytes) / Math.log(1024)).to_i
  exponent = [exponent, units.size - 1].min
  
  converted = bytes.to_f / (1024 ** exponent)
  "#{format('%.2f', converted)} #{units[exponent]}"
end

#main_appObject

Helper to get the main app’s routes



9
10
11
# File 'app/helpers/active_storage_dashboard/application_helper.rb', line 9

def main_app
  Rails.application.class.routes.url_helpers
end


44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'app/helpers/active_storage_dashboard/application_helper.rb', line 44

def pagination_links(total_count, per_page = 20)
  return if total_count <= per_page
  
  total_pages = (total_count.to_f / per_page).ceil
  current_page = [@page.to_i, 1].max
  
   :div, class: 'pagination' do
    html = []
    
    if current_page > 1
      html << link_to('« Previous', "#{request.path}?page=#{current_page - 1}", class: 'pagination-link')
    else
      html << (:span, '« Previous', class: 'pagination-link disabled')
    end
    
    # Show window of pages
    window_size = 5
    window_start = [1, current_page - (window_size / 2)].max
    window_end = [total_pages, window_start + window_size - 1].min
    
    # Adjust window_start if we're at the end
    window_start = [1, window_end - window_size + 1].max
    
    # First page
    if window_start > 1
      html << link_to('1', "#{request.path}?page=1", class: 'pagination-link')
      html << (:span, '...', class: 'pagination-ellipsis') if window_start > 2
    end
    
    # Page window
    (window_start..window_end).each do |page|
      if page == current_page
        html << (:span, page, class: 'pagination-link current')
      else
        html << link_to(page, "#{request.path}?page=#{page}", class: 'pagination-link')
      end
    end
    
    # Last page
    if window_end < total_pages
      html << (:span, '...', class: 'pagination-ellipsis') if window_end < total_pages - 1
      html << link_to(total_pages, "#{request.path}?page=#{total_pages}", class: 'pagination-link')
    end
    
    if current_page < total_pages
      html << link_to('Next »', "#{request.path}?page=#{current_page + 1}", class: 'pagination-link')
    else
      html << (:span, 'Next »', class: 'pagination-link disabled')
    end
    
    safe_join(html)
  end
end

#previewable_attachment?(attachment) ⇒ Boolean

Check if an attachment can be previewed

Returns:

  • (Boolean)


161
162
163
164
165
# File 'app/helpers/active_storage_dashboard/application_helper.rb', line 161

def previewable_attachment?(attachment)
  return false unless attachment&.blob&.present?
  
  previewable_blob?(attachment.blob)
end

#previewable_blob?(blob) ⇒ Boolean

Check if a blob can be previewed

Returns:

  • (Boolean)


110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'app/helpers/active_storage_dashboard/application_helper.rb', line 110

def previewable_blob?(blob)
  return false unless blob.present?
  
  # Check for representable content based on content type
  content_type = blob.content_type
  return false unless content_type.present?
  
  image_types = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']
  return true if image_types.include?(content_type)
  
  # Check for previewable content in Rails 6+ using Active Storage's previewable method
  if defined?(ActiveStorage::Blob.new.preview) && 
     blob.respond_to?(:previewable?) && 
     blob.previewable?
    return true
  end
  
  false
end

#rails_blob_url(blob, disposition: nil) ⇒ Object

Helper to generate a URL for direct blob viewing (for embedding media)



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'app/helpers/active_storage_dashboard/application_helper.rb', line 14

def rails_blob_url(blob, disposition: nil)
  # For media embedding, we need a reliable URL to the blob
  if defined?(request) && request.present?
    # Get the proper host from the request
    host = request.base_url
    
    # Different approaches depending on Rails version
    if Rails.gem_version >= Gem::Version.new('6.1') && Rails.application.routes.url_helpers.respond_to?(:rails_storage_proxy_path)
      # Rails 6.1+ uses proxy approach
      return host + Rails.application.routes.url_helpers.rails_storage_proxy_path(blob, disposition: disposition)
    elsif Rails.application.routes.url_helpers.respond_to?(:rails_service_blob_path)
      # Rails 5.2-6.0
      return host + Rails.application.routes.url_helpers.rails_service_blob_path(blob.key, disposition: disposition)
    elsif Rails.application.routes.url_helpers.respond_to?(:rails_blob_path)
      # Another approach
      return host + Rails.application.routes.url_helpers.rails_blob_path(blob, disposition: disposition)
    end
  end
  
  # Fallback to direct service URL
  if blob.respond_to?(:url)
    return blob.url(disposition: disposition)
  elsif blob.respond_to?(:service_url)
    return blob.service_url(disposition: disposition)
  end
  
  # Last resort - return path to download action in our engine
  active_storage_dashboard.download_blob_path(blob)
end

#variant_record_path(variant_record) ⇒ Object



285
286
287
# File 'app/helpers/active_storage_dashboard/application_helper.rb', line 285

def variant_record_path(variant_record)
  active_storage_dashboard.variant_record_path(variant_record)
end

#variant_records_pathObject



281
282
283
# File 'app/helpers/active_storage_dashboard/application_helper.rb', line 281

def variant_records_path
  active_storage_dashboard.variant_records_path
end