I am getting a trouble, trying to use CarrierWave for a file upload Rest API developed in Rails 3, with a MongoDB database.
What I would like to do is storing some files (not only images but every file format) with the MongoDB system GridFS.
I read many documentations that recommend my to use the CarrierWave gem.
But I have an error when I try to configure it.
My development environment :
The Gemfile :
source 'https://rubygems.org'
gem 'rails', '3.2.8'
# MongoDB
gem 'mongoid', :git => 'git://github.com/mongoid/mongoid.git'
gem 'carrierwave', :git => "git://github.com/jnicklas/carrierwave.git"
# gem 'carrierwave-mongoid', :require => 'carrierwave/mongoid'
gem 'mini_magick', :git => 'git://github.com/probablycorey/mini_magick.git'
gem 'bson_ext'
gem 'json'
The application.rb :
require File.expand_path('../boot', __FILE__)
# ActiveRecord will not be use with MongoDB
# require 'rails/all'
require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"
require "rails/test_unit/railtie"
require "sprockets/railtie"
require "mongoid/railtie"
require "carrierwave"
# require "carrierwave/mongoid"
I define the database with a mongoid.yml (config/mongoid.yml) file :
development:
sessions:
default:
database: lf_rest_api_development
hosts:
- localhost:27017
options:
consistency: :strong
options:
test:
sessions:
default:
database: lf_rest_api_test
hosts:
- localhost:27017
options:
consistency: :strong
And load it with an initializer (config/initializers/mongoid.rb) :
Mongoid.load!("config/mongoid.yml")
— I can execute the “rails server” command without problems after the last file, config/initializers/carrierwave.rb :
CarrierWave.configure do |config|
config.grid_fs_database = Mongoid.database.name
config.grid_fs_host = Mongoid.config.master.connection.host
config.storage = :grid_fs
config.grid_fs_access_url = "/files"
end
And then get the following error when I run the “rails server” command :
=> Booting WEBrick
=> Rails 3.2.8 application starting in development on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
Exiting
/{API_path}/config/initializers/zcarrierwave.rb:4:in `block in <top (required)>': undefined method `database' for Mongoid:Module (NoMethodError)
[...]
My file model is defined as following :
require 'carrierwave/orm/mongoid'
class File
include Mongoid::Document
store_in_collection: "files", database: "lf_rest_api_developement", session: "default"
key :filename, type: String
key :content_type, type: String
key :length, type: BigDecimal
key :chunk_size, type: Integer, :default => 256
key :upload_date, type: DateTime
key :md5, type: String
key :metadata, type: Array, :default => []
mount_uploader :file, FileUploader
index({ location: "2d" }, { min: -200, max: 200 })
end
The FileUploader is just an extension of CarrierWave uploader…
class FileUploader < CarrierWave::Uploader::Base
storage :grid_fs
end
Sorry about the slow response. Firstly, the reason for your error is that Mongoid 3 no longer supports
Mongoid.database. You can now find these configurations in theMongoid::Config.sessions[:default]object.BUT THIS AIN’T GONNA FIX YOUR PROBLEM! Mongoid 3 has no GridFS support at all. From mongoid docs:
So rather than seek other ways to store uploads in the GridFS at the expense of performance, I would suggest just throwing them in a SQL database. If your using Mongo as your only database, don’t be put off by this option. It’s not very difficult to get ActiveRecord and Mongoid working together side-by-side. But from my experience, uploading binary objects to any database may not perform well. I would personally use a filesystem for storage, with carrierwave or paperclip taking care of the management. Alternatively, I would suggest checking out some cheap cloud storage options. You can use something like aws-s3, a great service. It also has very well documented compatibility with Carrierwave.
If you are determined to use GridFS, I would check out the mongoid-grid_fs gem or check out some alternative ruby MongoDB drivers on the 10gen website.