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.