Search code examples
rubyruby-on-rails-5sidekiqrails-activestorage

ActiveStorage intermittently returning "Couldn't find ActiveStorage::Blob with 'id'"


I have a simple controller spec, which is supposed to check the processing for a new Material is queued when the item is created.

materials_controller_spec.rb (#create):

  it 'queues the processing of the material' do
    post :create, params: { material: valid_attributes }, session: valid_session

    expect(ProcessMaterialJob).to(
      have_been_enqueued.with(material_id: Material.last.id, video_filepath: Material.last.video_filepath)
    )
  end

When run in isolation it's fine, but when I run the whole suite with rspec . I get the following error:

 ActiveJob::DeserializationError:
   Error while trying to deserialize arguments: Couldn't find ActiveStorage::Blob with 'id'=418
 # ./spec/controllers/materials_controller_spec.rb:81:in `block (4 levels) in <top (required)>'
 # ------------------
 # --- Caused by: ---
 # ActiveRecord::RecordNotFound:
 #   Couldn't find ActiveStorage::Blob with 'id'=418
 #   ./spec/controllers/materials_controller_spec.rb:81:in `block (4 levels) in <top (required)>'

There have been a couple of points where I've not been convinced the attachment has been fully uploaded before the next page has rendered. I am concerned this could mean an issue with the file uploads. I followed the guide on direct uploads but I still see no progress indicator when uploading the video files, which are quite large.

My questions are:

  1. What is causing the strange Couldn't find ActiveStorage::Blob with 'id'=418 issue?
  2. How can I debug the file upload if that's where the issue is?

Thanks in advance!


Solution

  • I'd previously added ActiveJob::Base.queue_adapter = :test to my rails_helper.rb so it should have worked. However, adding that line into the particular test seemed to resolve the issue.

    it 'queues the processing of the material' do
      post :create, params: { material: valid_attributes }, session: valid_session
    
      expect(ProcessMaterialJob).to(
        have_been_enqueued.with(material_id: Material.last.id, video_filepath: Material.last.video_filepath)
      )
    end