Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Ruby
branch: master

bug fix for file system permission

latest commit 407f1d2dd6
Adilson Chacon Cavalcanti authored
Failed to load latest commit information.
lib bug fix for file system permission
test Interpolate any method ofmodel into url and path
Gemfile Now is Mongo Mapper 0.9.x compatible
LICENSE monving from mm-image-it ti mm-atach-it
README
README.rdoc
Rakefile Gem changes
mm-attach-it.gemspec bug fix for file system permission

README.rdoc

Mm-attach-it

Attach files (images, videos, pdfs, txts, zips and etc) to a MongoMapper record. You can even choose to store them on file system or GridFS.

Install

sudo gem install mm-attach-it

Or add it to your Rails’s Gemfile

gem "mm-attach-it"

If you are using Mongo Mapper 0.8.x or later

gem "mm-attach-it", "~> 0.1.5"

Usage

Model

Declare the plugin and use the attachment method to make attachments.

class Foo
  include MongoMapper::Document
  plugin AttachIt

  has_attachment :photo
end

The default storage destination is the file system, if you want to change it to GridFS you should add the following:

class Bar
  include MongoMapper::Document
  plugin AttachIt

  has_attachment :photo, { :storage => 'gridfs' }
end

If you want to resize the images (you can store resized images on both: file systems or GridFS):

class Foo
  include MongoMapper::Document
  plugin AttachIt

  has_attachment :photo, { :styles => { :small => '100x100>', :medium => '200x200>' } }
end

If you want to validate the attached file (again, you can validate attachments on both: file system or GridFS):

class Foo
  include MongoMapper::Document
  plugin AttachIt

  has_attch :photo

  validates_attachment_presence :photo
  validates_attachment_content_type :photo, :content_type => ['image/jpeg', 'image/gif', 'image/png']
  validates_attachment_size :photo, { :less_than => 1.megabyte, :greater_than => 500.kilobytes }
end

OBS: But remember! You can attach any desirable file.

If you are using the file system to store files, you can specify the directory/folder to store them.

class Foo
  include MongoMapper::Document
  plugin AttachIt

  has_attachment :photo, { :path => '/:rails_root/public/images/foos/:id/:style/:filename' }
end

OBS: The default directory is ’/:rails_root/public/system/:attachment/:id/:style/:filename’

Also you can interpolate any method result of the model

class Foo
  include MongoMapper::Document
  plugin AttachIt
  has_attachment :photo, { :url => '/:model.say_greet/users/:model.say_farewell/:id/:filename', :path => ':rails_root/public/:model.say_greet/:model.say_farewell/users/:id/:filename' }

  def say_greet
    'hello'
  end

  def say_farewell
    'bye'
  end
end

Where:

  • :rails_root - is the root directory of your Rails application

  • :environment - can be “production”, “test” or “development”

  • :class - the name of the class (in the example given above, ‘foo’)

  • :attachment - is the name of the column’s collection (in the example given above, ‘photo’)

  • :id - the “id” of the record on MongoDB

  • :style - if you specified the styles

  • :filename - the name of the file

  • :extension - the extension of the file

  • :model.METHOD_NAME - where METHOD_NAME is any method of the model

View

Check the model below

class Foo
  include MongoMapper::Document
  plugin AttachIt

  # on file system
  has_attachment :photo, { 
    :styles => { :thumb => '100x100>' },
    :url => '/assets/groups/:id/:style/:filename', 
    :path => '/:rails_root/public/image/foos/:id/:style/:filename'
  }

  # on GridFS
  has_attachment :avatar, {
    :styles => { :thumb => '100x100>' }, 
    :storage => 'gridfs', 
  }
end

Within forms you must set the “multipart” option and the field as “file_field”:

<%= form_for(@foo, :html => { :multipart => true }) do |f| %>

  <p>
    <%= f.label :photo %>
    <%= f.file_field :photo %>
  </p>

  <p>
    <%= f.label :avatar %>
    <%= f.file_field :avatar %>
  </p>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

Regardless of using the file system or GridFS the safest way to present the images is using Base64.

<img src="<%= foo.photo.base64 %>">
<img src="<%= foo.photo.base64('thumb') %>">

<img src="<%= foo.avatar.base64 %>">
<img src="<%= foo.avatar.base64('thumb') %>">

Also, specifically when using the file system, if you specify the ‘url’ option, you can do:

<%= image_tag foo.photo.url %>
<%= image_tag foo.photo.url('thumb') %>

Controller

If you are using the GridFS to store files, and you don’t want to use Base64 data to present the images, you’ve got to create an action on a controller.

But first create a new route on the route’s file:

match '/foos/avatar/:id(/:style)', :to => 'foos#avatar'

Now the controller:

class FoosController < ApplicationController

  ...

  def avatar
    foo = Foo.where('_id' => BSON::ObjectId(params[:id])).first
    grid_io_data = (params[:style].nil?) ? foo.avatar.get_from_gridfs : foo.avatar.get_from_gridfs(params[:style])
    bytes = grid_io_data.read
    send_data(bytes, :type => foo.avatar_content_type, :disposition => 'inline')
  end

  ...

end

And, for the view, do that:

<%= image_tag  "/foos/avatar/#{foo.id.to_s}/small" %>

Note on Patches/Pull Requests

  • Fork the project.

  • Make your feature addition or bug fix.

  • Add tests for it. This is important so I don't break it in a future version unintentionally.

  • Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)

  • Send me a pull request. Bonus points for topic branches.

Copyright

Copyright © 2010 Adilson Chacon. See LICENSE for details.

Something went wrong with that request. Please try again.