我正在使用CarrierWave将文件存储在gridfs中,但是从我的模型中打开它们时遇到了问题。 这是我的配置:
/config/initialize/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
/app/controllers/gridfs_controller.rb
/require 'mongo'
class GridfsController < ActionController::Metal
def serve
gridfs_path = env["PATH_INFO"].gsub("/files/", "")
begin
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
self.status = :file_not_found
self.content_type = 'text/plain'
self.response_body = ''
end
end
end
/app/uploaders/list_uploader.rb
class ListUploader < CarrierWave::Uploader::Base
storage :grid_fs
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
和路线
match "/files/uploads/*path" => "gridfs#serve"
所以,我有一个模型,它有一个文本文件
class Campaign
include Mongoid::Document
mount_uploader :list, ListUploader
当我从我的视图中调用类似<%=link_to "List", @campaign.list.url %>
的内容时,它打开正常。但是,当我从广告系列模型尝试类似File.open("#{campaign.list.url}", "r")
的内容时,它会失败。即使我正在调用false
,它也会给我File.exists?("/files/uploads/campaign/list/4eb02c4d6b1c0f02b200000b/list.txt")
,这是该文件的正确网址。那么,问题是如何调用它,从模型中打开文件?由于某些原因,从模型中打开它很重要。任何建议都会有所帮助,谢谢。
答案 0 :(得分:2)
带有mongodb gridfs的Carrierwave网址不是物理路径。它只是从gridfs下载文件的逻辑路径。这就是为什么你不能从ruby File.open
访问它。从rails console尝试从gridfs
File.open(User.first.image.pic.url,'r')
Errno::ENOENT: No such file or directory - /images/uploads/e5a1007d34.jpg
看到它抛出没有这样的文件或目录。所以你必须下载文件而不是打开
>> require 'open-uri'
>> open('image.jpg', 'wb') do |file|
?> file << open('http://0.0.0.0:3000' + (User.first.image.pic.url)).read
>> p file
>> end
#<File:image.jpg>
=> #<File:image.png (closed)>