Overview:

While upgrading a rails application from rails (3.0.10) to rails (3.1.12), we encountered a gem attachment_fu that needed to be replaced either by the famous Paperclip or Carrierwave or any other gem of your own choice. The reason being attachment_fu is a plugin and plugins support is no more available in rails latest version. We upgraded our Client’s project application to Paperclip, below were the steps for migration:

Migration Steps:

To meet the requirement, we added gem paperclip and its dependency cocaine in our Gemfile by running the following commands:
gem “paperclip”, “~> 3.0.4”
gem “ rmagick”
gem ‘cocaine’, ‘0.3.1’

We had to run gem install rmagick command in our project root directory console. Then checked if we had installed ImageMagick in our system or not. In our case it wasn’t, then we installed it first. After installation, we followed Github gist to migrate attachment_fu to paperclip. Following is our migration content:

class ConvertImagesToPaperclip < ActiveRecord::Migration
      include PaperclipMigrations
      require "#{Rails.root}/app/models/ticket.rb"
def self.up
      # Paperclip columns
      add_column :tickets, :image_file_name, :string
      add_column :tickets, :image_content_type, :string
      add_column :tickets, :image_file_size, :integer
      add_column :tickets, :image_updated_at, :datetime

      # Update table information
      Ticket.reset_column_information

      # Migrate data
      Ticket.all.each do |model|
       populate_paperclip_from_attachment_fu(model, model, 'image', 'tickets') if model
       file_path = ("%08d" % model.id).scan(/..../).join('/')
       old_path = File.join(Rails.root, 'public', 'tickets', file_path, model.filename)
           if File.exists?(old_path)
                model.image.reprocess!
           end
        end

      # After data migration and paperclip reprocessing remove attachement_fu columns
        remove_column :tickets, :filename
        remove_column :tickets, :content_type
        remove_column :tickets, :size
   end

def self.down
  raise ActiveRecord::IrreversibleMigration, "Can't recover the deleted data (Image)."
 end
end

Our migration module is placed in app/models/paperclip_migrations.rb file, and its code is:

module PaperclipMigrations

       def self.included(base)
                base.extend ClassMethods
       end

  module ClassMethods

      def populate_paperclip_from_attachment_fu(model, attachment, prefix, path_prefix)
           unless attachment.filename.nil?
           model.send("#{prefix}_file_name=", attachment.filename)
           model.send("#{prefix}_content_type=", attachment.content_type)
           model.send("#{prefix}_file_size=", attachment.size)

           # Get file path from attachment_fu
           file_path = ("%08d" % model.id).scan(/..../).join('/')
           old_path = File.join(Rails.root, 'public', path_prefix, file_path,
attachment.filename)
           new_path = model.send(prefix).path(:original)
           new_folder = File.dirname(new_path)

           if File.exists?(old_path)
                     unless File.exists?(new_folder)
                              FileUtils.mkdir_p(new_folder)
                     end
                     puts "Copying #{old_path} to #{new_path}"
                     `cp #{old_path} #{new_path}`
                     model.save!
                 else
                     puts "No such file: #{old_path}"
                 end
       end
   end
end

In our model that uses images, we replaced this code:

has_attachment :content_type => :image,
        :storage => :file_system,
        :max_size => 5000.kilobytes,
        :resize_to => '320x200>',
        :thumbnails => { :thumb => '100x100>' }

With the code below:

attr_accessible :image
has_attached_file :image, styles: { thumb: "100x100>" }
validates_attachment_content_type :image, content_type: /\Aimage\/.*\Z/,
         storage: :file_system, max_size: 5000.kilobytes,
      resize_to: '320x200>',thumbnails: { :thumb => '100x100>' }

Now we ran migration to migrate our images data and generated paperclip columns in the database. Then checked if paperclip was generating all styles of images mentioned in our model or not. In our case, thumbnails were extra style of images. The reprocess! method of paperclip was not generating thumbnail images, then to resolve this we ran rake paperclip:refresh:missing_styles command. This command generated thumbnails as well as a file at public/system/paperclip_attachments.yml. If anyone wants to regenerate thumbnails, remove this file and run the above command again.

In views form, upload_data file was replaced with image field name. We also changed our code with respect to new columns of paperclip that were replaced by attachment_fu columns. For other views and code changes follow Paperclip code for application views, and then remove attachment_fu plugin.

0 Comments

Leave a Reply