Search code examples
rubyfile-uploadcarrierwaveruby-on-rails-4rmagick

Manually upload and save files in Carrierwave


I have a directory of existing files which I need to migrate into my rails app as part of a legacy migration. Essentially I need to upload these files manually and save a new record for them in the database. I haven't quite found the proper way to do this. Currently I have the following in a rake task:

@attachments.each do |attachment|
  begin
    new_attachment = Attachment.new

    @attachment_file_path = "/home/username/Attachments/" + attachment.Filename
    file = File.open(@attachment_file_path)
    new_attachment[:file] = new_attachment.file.store!(file)

    # Map old record fields to new
    new_attachment.attributes = {
        :project_id => attachment.ProjectID,
        :name => attachment.Description,
        :user_id => attachment.UserId,
        :created_at => attachment.CreatedDate,
        :updated_at => attachment.LastModifiedDate
    }

    new_attachment.save!

    puts "Attachment added successfully "

  rescue => error
    puts "Error migrating Attachment: #{error}"
  end
end

attachment.rb

class Attachment < ActiveRecord::Base
     mount_uploader :file, FileUploader
end

uploader:

class FileUploader < CarrierWave::Uploader::Base

  include CarrierWave::RMagick
  include CarrierWave::MimeTypes

  process :set_content_type
  storage :fog

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  def extension_white_list
    %w(jpg jpeg gif png pdf doc docx txt)
  end

  version :thumb do
    process resize_to_fit: [152, nil]
  end

  def default_url
      ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
  end

  protected
    def image?(new_file)
      if new_file.content_type == nil
        return false
      else
        new_file.content_type.include? 'image'
      end
    end


end

This does not work currently. The file never gets uploaded, and occasionally I get the following error:

Failed to manipulate with rmagick, maybe it is not an image? Original Error: no decode delegate for this image format

In this instance, the file is a '.doc' file.

What is the correct way to open a local file and upload it manually via Carrierwave?

Any help is appreciated.


Solution

  • Try this

    @attachments.each do |attachment|
      begin
        options =  {
            :project_id => attachment.ProjectID,
            :name => attachment.Description,
            :user_id => attachment.UserId,
            :created_at => attachment.CreatedDate,
            :updated_at => attachment.LastModifiedDate,
            :file => File.new(File.join("/home/username/Attachments/",attachment.Filename)) 
        }
    
         new_attachment = Attachment.new(options)
       
    
        new_attachment.save!
    
        puts "Attachment added successfully "
    
      rescue => error
        puts "Error migrating Attachment: #{error}"
      end
    end
    

    Perhaps that would do for you as carrierwave would internally call store! for you

    Question?

    Failed to manipulate with rmagick, maybe it is not an image? Original Error: no decode delegate for this image format
    

    Not sure what are you trying to over here because you have define an image? method which is not specified in condition also is that something that you want the content_type to be only present for image file

    if no perhaps only the process call would work

    process :set_content_type

    if yes then perhaps you have to do something like this

    process :set_content_type , :if => :image?
    
    def image?(new_file)
      %w(jpg jpeg gif).include?(new_file.extension)
    end
    

    Hope this help

    EDIT based upon the comment

    try this just used the condition same logic

       version :thumb ,:if => image? do
         // your code 
       end