Как открыть файл, который хранится в CarrierWave в GridFs из модели рельсов?(File.open проблема) - PullRequest
1 голос
/ 01 ноября 2011

Я использую CarrierWave для хранения файлов в gridfs, но у меня проблемы с открытием их из моей модели. Вот мои конфиги:

/ конфигурации / инициализации / 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

/ приложение / контроллеры / 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

/ приложение / закачивающие / 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"), который является правильным URL для этого файла. Итак, вопрос в том, как мне это назвать, чтобы открыть файл из модели? И по ряду причин важно открыть его из модели. Любые предложения помогут, спасибо.

1 Ответ

2 голосов
/ 02 ноября 2011

URL-адрес Carrierwave с сеткой mongodb - это не физический путь. Это просто логический маршрут для загрузки файла из gridfs. Вот почему вы не можете получить к нему доступ через ruby ​​File.open. Посмотрите на приведенный ниже фрагмент из консоли rails, пытаясь открыть файл из 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)>
...