greyoxide
greyoxide

Reputation: 1287

ActiveStorage::FileNotFoundError (ActiveStorage::FileNotFoundError) in server log, but not reproducable in console

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?

Upvotes: 3

Views: 2546

Answers (3)

Abdul Rehman
Abdul Rehman

Reputation: 742

I came across the same issue and after some digging on the internet here is what I have found

  1. As pointed out by @greyoxide, It is mentioned in the official documentation that the file will only be available in the after_create_commit hook and not in after_create.

  2. From here, Figured that it will only work if has_one_attached :file or has_many_attached :files is executed before the after_create_commit hook and for that you might have to change the order of the lines inside the model i.e

      class Footer < ApplicationRecord
        after_create_commit :transload_files
    
        has_many_attached :files
    

Upvotes: 0

Pere Joan Martorell
Pere Joan Martorell

Reputation: 3093

In my case, what I noticed is that attaching attachments with ActiveStorage is not working properly when doing it inside a transaction. This applies to migrations or callbacks.

Upvotes: 4

greyoxide
greyoxide

Reputation: 1287

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.

Upvotes: 7

Related Questions