I have the following model:
class Section < ApplicationRecord
has_many_attached :files
def to_dir
[client.to_dir, operation.to_dir, self.name.parameterize].join('/')
end
after_save :transload_files
def transload_files
TransloadService.sync( self.to_dir, self.files )
end
end
The transload_files
method is the issue. Here is the transload service:
class TransloadService
class << self
def sync(check_dir, files)
# First we have to check the transload dir for files that have been deleted on the app
transloaded_files = Request.list(check_dir)
cull_list = transloaded_files.reject{ |e| files.map{|t| t.filename }.include? Request.filename(e)}
if cull_list.count > 0
Request.trim(cull_list)
p "#{cull_list.count} files trimed from #{check_dir}."
end
# Next we have to upload files which arent present in the transload dir
send_list = files.reject{ |e| transloaded_files.map{|t| Request.filename(t) }.include? e.filename.to_s }
if send_list.count > 0
Request.upload_to(check_dir, send_list)
p "#{send_list.map{|r| r.filename.to_s}.join(', ')} uploaded to #{check_dir}"
end
end
end
end
and here is the relevant code in request.rb
class Request
class << self
def upload_to(destination, files)
files.each do |file|
send_to = connection.object("#{destination}/#{file.filename}")
file.open{ |tmp| send_to.upload_file(tmp) }
end
end
end
end
The issue I'm facing is this: When the after_save
callback runs the transload_files method it returns
ActiveStorage::FileNotFoundError (ActiveStorage::FileNotFoundError)
When I run the Section.last.transload_files
in the console, it performs exactly as intended. What am I missing here?
After experimenting for about two days I've simply come to the conclusion that though an ActiveStorage record is created, it will be unavailable in any model callbacks. The official AS documentation references the after-create-commit
callback here, However I was unable to call blob.open
or blob.download
like the included example. From the console it works however.
I was able to address this issue by calling a job from the Section model then calling the transload service from the job.