DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone >

Generic File And Image Models For Uploaded Files

Snippets Manager user avatar by
Snippets Manager
·
Oct. 08, 05 · · Code Snippet
Like (0)
Save
Tweet
518 Views

Join the DZone community and get the full member experience.

Join For Free
These are basic models that store a file in a dedicated files table.  Use has_one or has_many to associate this with your actual models.  RMagick is required for images.

This is my first code dealing with uploads and rmagick, so please comment if you have suggestions.

class DbFile < ActiveRecord::Base
  IMAGE_TYPES = ['image/jpeg', 'image/pjpeg', 'image/gif', 'image/png', 'image/x-png']
  before_validation     :sanitize_filename
  validates_presence_of :size, :filename, :content_type

  class << self
    def new_file(file_data)
      content_type = file_data.content_type.strip
      (IMAGE_TYPES.include?(content_type) ? DbImage : DbFile).new \
        :data         => file_data.read,
        :filename     => file_data.original_filename,
        :size         => file_data.size,
        :content_type => content_type
    end
  end

  protected
  def sanitize_filename
      # NOTE: File.basename doesn't work right with Windows paths on Unix
      # get only the filename, not the whole path
      filename.gsub! /^.*(\\|\/)/, ''

      # Finally, replace all non alphanumeric, underscore or periods with underscore
      filename.gsub! /[^\w\.\-]/, '_'
  end
end

require 'rmagick'
require 'base64'
class DbImage < DbFile
  def data=(file_data)
    with_image(file_data, true) do |img|
      self.width  = img.columns
      self.height = img.rows
    end
  end

  def with_image(file_data = nil, save_image = false, &block)
    img = Magick::Image::read_inline(Base64.b64encode(file_data || self.data)).first
    block.call(img)
    write_attribute('data', img.to_blob) if save_image
    img = nil
    GC.start
  end
end

Controller Usage:

# returns DbImage if content_type matches
db_file = DbFile.new_file(params[:file][:data])
db_file.save

Model Usage:

# raw binary image data
File.open('my_file', 'w') { |f| f.write(db_file.data) }

# Image resizing with rmagick
# automatically creates RMagick::Image and 
# invokes GC.start
db_file.with_image do |img|
  img.scale(.25)
  img.write('thumb.jpg')
end

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • How to Integrate Zoom in React Application?
  • Handling Sensitive Data: A Primer
  • Ultra-Fast Microservices in Java: When Microstream Meets Open Liberty
  • The Most Popular Technologies for Java Microservices Right Now

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo