A Nunemaker Joint »
Created at: 27.03.2010 05:00, source: RailsTips - Home, tagged: joint mongomapper gems gridfs
Since The Changelog has already scooped me (darn those guys are fast), I figured I should post something here as well. Last December I posted Getting a Grip on GridFS. Basically, I liked what Grip was doing, but made a few tweaks. Grip’s development has continued, but it is headed down a bit different path, so I thought it might be confusing to keep my fork named the same.
Today, I did some more work on the project and now that it is unrecognizable when compared to Grip, I renamed it to Joint. Yes, I realize that I now have gems named crack and joint. Joint is a tiny piece of code that joins MongoMapper and the new Ruby GridFS API.
Usage
What I love about joint is its simplicity. Simply declare the attachment and you are good to go.
class Asset
include MongoMapper::Document
plugin Joint # add the plugin
attachment :file # declare an attachment named image
end
With that simple declaration, you get #file and #file= instance methods and several keys (file_id, file_name, file_type, and file_size). The #file instance method returns a simple proxy to make the API a bit prettier and sends all other calls on the proxy to the GridIO instance.
asset = Asset.create(:file => params[:file])
asset.file.id # GridFS Object Id
asset.file.name # file name
asset.file.type # mime type as determined by wand gem
asset.file.size # size in bytes
There is no limit to the number of attachments, but each attachment uses 4 keys so I would not add more than one or two (more is a sign you are doing something wrong). As mentioned in the comment above, it uses my wand project to determine the mime type.
For those that are not familiar with wand (as I have not posted here about it), it first attempts to determine the mime type using the mime-types gem. If that fails to returning anything, it drops down to the unix file command.
What It Does Not Do
Anything else. All joint handles is assigning a file and storing it in GridFS. It doesn’t do versions, resizing, etc. For this type of stuff, I would recommend imagery with some HTTP caching (varnish, et el.) sitting in front of it.
I can certainly see having some triggers (callbacks) at some point such as after jointed or something for when you do want to do post processing. I’ll leave that for a rainy day though.
more »
Getting A Grip on GridFS »
Created at: 23.12.2009 16:30, source: RailsTips - Home, tagged: gridfs mongodb mongomapper plugin
In which I announce some tweaks I made to a fun plugin which makes storing files in GridFS as easy as 1, 2, 3.
I know it is almost Christmas and your minds are beginning to turn to gifts and family, but hang with me for a few more minutes. My buddy Jon pointed me to Grip yesterday. I liked the idea but not all of the implementation. I’ve been doing some GridFS stuff lately so I decided to take some time and tweak it to be more what I need.
You can get my fork of Grip on Github. Below is a simple example of how it works (you could also check out the tests).
class Foo
include MongoMapper::Document
include Grip
has_grid_attachment :image
has_grid_attachment :pdf
end
image = File.open('foo.png', 'r')
pdf = File.open('foo.pdf', 'r')
foo = Foo.create(:image => image, :pdf => pdf)
foo.image # contents read from gridfs for serving from rack/metal/controller
foo.image_name # foo.jpg
foo.image_content_type # image/png
foo.image_size # File.size of the file
foo.image_path # path in grid fs foo/image/:id where :id is foo.id
The main changes I made were to store name, size and content_type along with the path to the file. I also made it so those are assigned when the file is set so that they can be used in validations. Some other ideas I have for the plugin are adding image resizing with MojoMagick and common validations (much like most of the file upload plugins out there).
What I really like about Grip is its simplicity. A single, small file, an include, a call to has_grid_attachment, and you can start storing files. The great thing about working on this is it gave me some wonderful ideas for how to standardize the process of creating and declaring MongoMapper plugins.
I’ll be adding those to ideas to MongoMapper over the next few weeks as I get time and I think people are going to be stoked about what I’ve come up with (thanks to Brandon for brainstorming the plugin API with me).
Behind the Scenes
As I said, behind the scenes, Grip uses GridFS (more on GridFS), Mongo’s specification for storing files in Mongo.
The good news is that the API for storing files in GridFS using Ruby is nearly identical to using Ruby’s File class. Unfortunately, that is also the bad news, in my opinion, as I find Ruby’s File open, read and close a bit awkward. Here are a few examples pulled almost directly from Grip:
# write foo.jpg to grid fs
file = File.read('foo.jpg')
GridFS::GridStore.open(database, 'foo.jpg', 'w', :content_type => 'image/jpg') do |f|
f.write(file)
end
# read foo.jpg from grid fs
GridFS::GridStore.read(database, 'foo.jpg')
# delete foo.jpg from grid fs
GridFS::GridStore.unlink(database, 'foo.jpg')
Not horrible but not beautiful. There is a bunch of GridFS related code on Github. To highlight a few interesting ones:
That is all for now. Enjoy the GridFS goodness and the future hope of an awesome MongoMapper plugin interface.
more »
Getting A Grip on GridFS »
Created at: 23.12.2009 16:30, source: RailsTips - Home, tagged: mongodb plugin mongomapper gridfs
I know it is almost Christmas and your minds are beginning to turn to gifts and family, but hang with me for a few more minutes. My buddy Jon pointed me to Grip yesterday. I liked the idea but not all of the implementation. I’ve been doing some GridFS stuff lately so I decided to take some time and tweak it to be more what I need.
You can get my fork of Grip on Github. Below is a simple example of how it works (you could also check out the tests).
class Foo
include MongoMapper::Document
include Grip
has_grid_attachment :image
has_grid_attachment :pdf
end
image = File.open('foo.png', 'r')
pdf = File.open('foo.pdf', 'r')
foo = Foo.create(:image => image, :pdf => pdf)
foo.image # contents read from gridfs for serving from rack/metal/controller
foo.image_name # foo.jpg
foo.image_content_type # image/png
foo.image_size # File.size of the file
foo.image_path # path in grid fs foo/image/:id where :id is foo.id
The main changes I made were to store name, size and content_type along with the path to the file. I also made it so those are assigned when the file is set so that they can be used in validations. Some other ideas I have for the plugin are adding image resizing with MojoMagick and common validations (much like most of the file upload plugins out there).
What I really like about Grip is its simplicity. A single, small file, an include, a call to has_grid_attachment, and you can start storing files. The great thing about working on this is it gave me some wonderful ideas for how to standardize the process of creating and declaring MongoMapper plugins.
I’ll be adding those to ideas to MongoMapper over the next few weeks as I get time and I think people are going to be stoked about what I’ve come up with (thanks to Brandon for brainstorming the plugin API with me).
Behind the Scenes
As I said, behind the scenes, Grip uses GridFS (more on GridFS), Mongo’s specification for storing files in Mongo.
The good news is that the API for storing files in GridFS using Ruby is nearly identical to using Ruby’s File class. Unfortunately, that is also the bad news, in my opinion, as I find Ruby’s File open, read and close a bit awkward. Here are a few examples pulled almost directly from Grip:
# write foo.jpg to grid fs
file = File.read('foo.jpg')
GridFS::GridStore.open(database, 'foo.jpg', 'w', :content_type => 'image/jpg') do |f|
f.write(file)
end
# read foo.jpg from grid fs
GridFS::GridStore.read(database, 'foo.jpg')
# delete foo.jpg from grid fs
GridFS::GridStore.unlink(database, 'foo.jpg')
Not horrible but not beautiful. There is a bunch of GridFS related code on Github. To highlight a few interesting ones:
That is all for now. Enjoy the GridFS goodness and the future hope of an awesome MongoMapper plugin interface.
more »
