最近准备将Everyday CMS的数据存储由MySQL切换到MongoDB,作为实验先探探路,看看能不能用MongoDB的GridFS来存储图片,下面具体的实现:
$ rails new demo
gem 'mongoid' #2.4.10
gem 'bson_ext' #1.6.2
gem 'carrierwave' #0.5.8
gem 'carrierwave-mongoid', :require => 'carrierwave/mongoid' #0.1.7
gem 'mini_magick' #3.4
$ rails g mongoid:config
require 'rails/all'
require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"
require "rails/test_unit/railtie"
config.generators do |g|
g.orm :active_record
end
$ rm -f config/database.yml
$ rails g scaffold blog name:string content:text
CarrierWave.configure do |config|
config.storage = :grid_fs
config.grid_fs_access_url = ""
config.grid_fs_database = Mongoid.database.name
config.grid_fs_host = Mongoid.config.master.connection.host
end
$ rails g uploader File
class FileUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
# Choose what kind of storage to use for this uploader:
storage :grid_fs
# Override the directory where uploaded files will be stored.
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
def default_url
"/uploads/fallback/" + [version_name, "default.png"].compact.join('_')
end
# Create different versions of your uploaded files:
version :thumb do
process :resize_to_fill=> [50, 50]
end
version :normal do
process :resize_to_fill => [150, 200]
end
version :big do
process :resize_to_fill => [250, 300]
end
version :large do
process :resize_to_fill => [350, 400]
end
def extension_white_list
%w(jpg jpeg gif png)
end
def filename
"something.jpg" if original_filename
end
end
$ rails g controller gridfs
class GridfsController < ActionController::Metal
def serve
gridfs_path = env["PATH_INFO"].gsub("/uploads/", "uploads/")
begin
puts "---------------------------------------"
puts gridfs_path
puts Mongoid.database.name
puts "---------------------------------------"
gridfs_file = Mongo::GridFileSystem.new(Mongoid.database).open(gridfs_path, 'r')
self.response_body = gridfs_file.read
self.content_type = gridfs_file.content_type
rescue Exception => e
self.status = :file_not_found
Rails.logger.debug { "#{e}" }
self.content_type = 'text/plain'
self.response_body = ''
raise e
end
end
end
if Rails.env.development?
match "/uploads/*path" => "gridfs#serve"
end
class Blog
include Mongoid::Document
field :name
field :content
field :file
mount_uploader :file, FileUploader
end
<%= f.label :file %>
<%= f.file_field :file %>
<%= blog.file.size %>
<%= blog.file.filename%>
<%= image_tag blog.file_url(:thumb)%>
<%= image_tag blog.file_url(:normal)%>
<%= image_tag blog.file_url(:big)%>
<%= image_tag blog.file_url(:large)%>
24 May 2012 Suzhou, China注意:尽量不要在rails3.1以下版本操作,否则会出现无法集成mongoid的问题,OK JSUT DO IT!