Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ActiveRecord setters and unique filenames with mount_uploaders/multiple #2247

Closed
krisdigital opened this issue Nov 6, 2017 · 0 comments
Closed

Comments

@krisdigital
Copy link

I am trying to achieve two things:

  1. Adding/deleting of files to/from the collection
  2. Sequential file names (if file test.jpg exists, name the next one test_2.jpg)
  3. Revisioning (Do not delete files, so old file paths are still valid)

Problems:

  1. When setting files on creation Model.create(files: [file1, file2, file3]) I think the filename method is called for all files before any of the files is stored, so if all files are named 'test.jpg', for all calls the file does not exist and the serialized json in the db is ['test.jpg', 'test.jpg', 'test.jpg']
  2. When adding files like model.files += [file4, file5] all files, even file1, file2 and file3 are reprocessed, and there is no way to distinguish already stored files, with the result that all files get new filenames and are stored again.

Model

  mount_uploaders :files, FileUploader

Uploader

class FileUploader < CarrierWave::Uploader::Base
  storage :file
  
  ...
  configure do |config|
    config.remove_previously_stored_files_after_update = false
  end

  def filename
    # Pseudo
    while File.exists? Pathname(root).join(store_path(final_name)) do
    # Rename file...
    end
  end
end

The only solution I could think of was using an ActiveRecord 'Helper' Model that adds the files, which is only possible after a record exists:

class OriginalModelFile < ApplicationRecord
  self.table_name = :original_models

  has_paper_trail

  def self.add_files(uploaded_files, model)
    return unless uploaded_files

    added_files = []
    uploaded_files.each do |file|
      uploader = FileUploader.new(model, :files)
      uploader.store!(file)
      added_files.push uploader.file.filename
    end
    omf = OriginalModelFile.find(model.id)
    existing_files = omf.files || []

    omf.update(files: existing_files + added_files, status: :initial)
    model.reload

    rescue CarrierWave::IntegrityError => e
      model.errors.add(:files, e.message)
  end

...

So as you can see this is a pretty big workaround.. Any ideas how to solve this problem?

What I think would help is a way to distinguish already stored Uploaders from the newly added ones.

I think this is where it happens:

def cache(new_files)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant