0
votes

Following Carrierwave and RailsAdmin instructions I can preform multiple uploads in RailsAdmin with Carrierwave, using aws S3. When trying to delete one of the images I get:

undefined method 'filename' for nil:NilClass

The assets field is a json field, assets:json

This is in my model:

attr_accessor :delete_assets
  after_validation do
    uploaders = assets.delete_if do |uploader|
      if Array(delete_assets).include?(uploader.file.filename)
        uploader.remove!
        true
      end
    end
    write_attribute(:assets, uploaders.map { |uploader| uploader.file.filename })
  end

I tried uploader.file.identifier but read that when using fog aws S3 the uploader.file.filename should be used.

My resources so far:

RailsAdmin https://github.com/carrierwaveuploader/carrierwave/blob/master/README.md#multiple-file-uploads

Carrierwave: https://github.com/sferik/rails_admin/wiki/CarrierWave

Stackoverflow: Rails Admin - undefined method `' for using Carrierwave multiple upload

How do I delete a previously uploaded image from this json array? Any help is much appreciated!

1

1 Answers

1
votes

The problem here is certain uploaders don't have a file attached. So your error is because you're calling filename on nil - aka uploader.file returns nil.

You'll likely want to handle this occurrence, something like the following:

  attr_accessor :delete_assets

  after_validation do
    uploaders = assets.delete_if do |uploader|
      next unless uploader.file # <-- skip deleting assets without a file

      if Array(delete_assets).include?(uploader.file.filename)
        uploader.remove!
        true
      end
    end
    write_attribute(:assets, uploaders.map { |uploader| uploader.file.filename })
  end

Or if you'd rather remove all assets missing a file:

  attr_accessor :delete_assets

  after_validation do
    uploaders = assets.delete_if do |uploader|
      next true unless uploader.file # <-- note 'true' added here

      if Array(delete_assets).include?(uploader.file.filename)
        uploader.remove!
        true
      end
    end
    write_attribute(:assets, uploaders.map { |uploader| uploader.file.filename })
  end

Otherwise, the route you'll need to go down will be validating the presence of a file on an uploader, which is likely a separate question.

Hope this helps - let me know how you get on or if you have any questions here :)