使用没有GridFS的mongoid在mongodb中保存pdf

时间:2015-06-23 07:53:32

标签: ruby mongodb mongoid bson padrino

我想在mongodb数据库中保存一个小的pdf文件。我使用Ruby(2.0.0),Padrino(0.12.5)和MongoId(3.0.0),MongoDB(2.6)。由于我的文件大小约为1MB,我不需要GridFS的复杂性。

我是MongoDB的新手,希望可以轻松保存小文件而不必担心路径和文件系统。

class Client
  include Mongoid::Document
  include Mongoid::Timestamps # adds created_at and updated_at fields

  field :last_name, :type => String
  field :cv_pdf, :type => Moped::BSON::Binary
 end

如果我在控制台中使用测试文件,当我想将pdf文件保存到数据库时出现错误:

2.0.0-p353 :015 >   c = Client.first
    => #<Client _id: 55883b5168874459df000001, _type: nil, created_at: 2015-06-22 16:44:01 UTC,
    updated_at: 2015-06-23 06:45:57 UTC, last_name: "Foo", cv_pdf: ""> 
2.0.0-p353 :016 > f = File.open("test1.pdf")
    => #<File:test1.pdf> 
2.0.0-p353 :017 > c.cv_pdf = f
    => #<File:test1.pdf> 
2.0.0-p353 :019 > c.save
  NoMethodError: undefined method `__bson_dump__' for #<File:test1.pdf> 
  [...]

2 个答案:

答案 0 :(得分:0)

使用ahoward/mongoid-grid_fs gem,改为保存GridFS文件ID。写一个setter和getter helper,以便于处理。

class Client
  field :cv_pdf_id, :type => String

  def set_cv_pdf(file_path)
    self.cv_pdf_id = Mongoid::GridFs.put( File.open(file_path) ).id
    self.save
  end

  def get_cv_pdf
    Mongoid::GridFs.get(cv_pdf_id)
  end
end

# Write
c = Client.new
c.set_cv_pdf('test1.pdf')

# Read
c.cv_pdf      # => #<Mongoid::GridFs::Fs::File:0x007fed8d8b6230>
c.cv_pdf.data # => Blob data

答案 1 :(得分:0)

您的问题是您正试图在MongoDB中存储File实例:

f = File.open("test1.pdf")
c.cv_pdf = f

但Mongoid / Moped / MongoDB知道如何处理File。这就是NoMethodError错误抱怨缺少__bson_dump__方法的意思:你给Mongoid一些不知道如何转换成MongoDB兼容数据的错误。

解决方案非常简单:阅读文件并将其内容提供给Mongoid:

c.cv_pdf = File.read('test1.pdf', :mode => 'rb')