2014-06-13 76 views
2

我试图让carrierwave + mongoid + gridfs通过padrino管理员上传图片,然后在前端显示。无所适从,无所适从。有人可以帮忙吗?Carrierwave + Mongoid + gridfs + Padrino管理图像上传

以下https://blog.engineyard.com/2011/a-gentle-introduction-to-carrierwave/https://github.com/carrierwaveuploader/carrierwave-mongoid

努力坚持的 “艺术品” 与图像上传回报:

NoMethodError在/管理/艺术品/更新/ 53a0eedcf2c7961066000002 未定义的方法`bson_dump'为#文件: hash.rb位置:块bson_dump线:15

mongofiles -d database list 

返回空。

问题是:此刻的代码有什么问题?

上传:https://github.com/bcsantos/debug/blob/master/lib/uploader.rb

class Uploader < CarrierWave::Uploader::Base 

    ## 
    # Image manipulator library: 
    # 
    include CarrierWave::RMagick 
    # include CarrierWave::ImageScience 
    # include CarrierWave::MiniMagick 

    ## 
    # Storage type 
    # 
    storage :grid_fs 
    # configure do |config| 
    # config.fog_credentials = { 
    #  :provider    => 'XXX', 
    #  :aws_access_key_id  => 'YOUR_ACCESS_KEY', 
    #  :aws_secret_access_key => 'YOUR_SECRET_KEY' 
    # } 
    # config.fog_directory = 'YOUR_BUCKET' 
    # end 
    # storage :fog 

resize_to_limit(1024, 768) 

    ## Manually set root 
    def root; File.join(Padrino.root,"public/"); end 

    ## 
    # Directory where uploaded files will be stored (default is /public/uploads) 
    # 
    def store_dir 
    'content' 
    end 

    ## 
    # Directory where uploaded temp files will be stored (default is [root]/tmp) 
    # 
    def cache_dir 
    Padrino.root("tmp") 
    end 

    ## 
    # Default URL as a default if there hasn't been a file uploaded 
    # 
    # def default_url 
    # "/images/fallback/" + [version_name, "default.png"].compact.join('_') 
    # end 

    ## 
    # Process files as they are uploaded. 
    # 
    # process :resize_to_fit => [740, 580] 

    ## 
    # Create different versions of your uploaded files 
    # 
    # version :header do 
    # process :resize_to_fill => [940, 250] 
    # version :thumb do 
    #  process :resize_to_fill => [230, 85] 
    # end 
    # end 
    ## 
    # White list of extensions which are allowed to be uploaded: 
    # 
    def extension_white_list 
    %w(jpg jpeg gif png) 
    end 

    ## 
    # Override the filename of the uploaded files 
    # 
    # def filename 
    # "something.jpg" if original_filename 
    # end 
end 

-----------

上传https://github.com/bcsantos/debug/blob/master/app/models/upload.rb

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

    # field <name>, :type => <type>, :default => <value> 
    field :file, :type => String 
    field :created_at, :type => Time 

    attr_accessible :upload 

    mount_uploader :upload, Uploader 


    # You can define indexes on documents using the index macro: 
    # index :field <, :unique => true> 

    # You can create a composite key in mongoid to replace the default id using the key macro: 
    # key :field <, :another_field, :one_more ....> 
end 

-----------

模型我想联想上传/图片与https://github.com/bcsantos/debug/blob/master/app/models/artwork.rb

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

    # field <name>, :type => <type>, :default => <value> 
    field :name, :type => String 
    field :year, :type => Integer 
    field :author, :type => String 
    field :rent_price, :type => String 
    field :sale_price, :type => String 
    field :medium, :type => String 
    field :size, :type => String 
    field :colour, :type => String 

    field :picture, :type => Upload 
    field :thumbnail, :type => Upload 


    # You can define indexes on documents using the index macro: 
    # index :field <, :unique => true> 

    # You can create a composite key in mongoid to replace the default id using the key macro: 
    # key :field <, :another_field, :one_more ....> 
end 

-----------

控制器从数据库中检索文件(感谢@达里奥)

TourApart::App.controllers do 

    get :gridfs, map: '/content/*' do 
    gridfs_file = Mongoid::GridFS[params[:splat]] 
    content_type gridfs_file.content_type 
    gridfs_file.data 
    end 

    error Mongoid::Errors::MongoidError do 
    halt 404, 'File not found' 
    end 

end 

回答

2

首先,鉴于此模型的设计,您的作品模型没有正确嵌入Upload文档。它应改为嵌入picturethumbnail场像这样:

class Artwork 
    # ... 
    embeds_one :picture, class_name: "Upload" 
    embeds_one :thumbnail, class_name: "Upload" 
    # ... 
end 

除此之外,我不明白你为什么摆在首位的Upload文件。给你的设计看起来没有必要。 Uploader包含您试图存储在Upload模型中的所有信息。例如,您的Artwork模型可以,而不是仅仅是这样的(你可以转储Upload模型一起):

class Artwork 
    # ... 
    mount_uploader :picture, Uploader 
    mount_uploader :thumbnail, Uploader 
    # ... 
end 

picturethumbnail场将举行东西就像是更新的日期,文件名,文件日期等。

此外,它看起来像你试图手动管理thumbnail。我认为缩略图是picture的较小版本。Carrierwave可以为你处理这个问题太:

class Artwork 
    # ... 
    mount_uploader :picture, Uploader 
    # ... 
end 

然后加入这样的事情你Uploader

class Uploader < CarrierWave::Uploader::Base 
    # ... 
    version :thumbnail do 
    process resize_to_fill: [160, 120] 
    end 
    # ... 
end 

这样的话,你就会有一个Artwork#pictureArtwork#picture_thumbnail访问两个不同的版本。

更多的例子:

  • Artwork#picture.read - 得到的图像数据
  • Artwork#picture.file - 得到的图像文件
  • Artwork#picture_thumbnail.file - 获得缩略图版本的文件
  • Artwork#picture.file.content_type - 烨,包括content_type

最后,如果你使用carrierwave-mongoid,没有必要直接在控制器中访问Mongoid::GridFS。查找作品并访问picture字段。让GridFS留在幕后。

除此之外,我会建议使用CarrierWave::MiniMagickCarrierWave::RMagick。从长远来看,它使事情变得更容易,IMO,但它需要你的机器上安装了ImageMagick。

0

这花了一段时间...帮助别人节省时间,这里有云:

的Gemfile

#... 
gem 'mongoid', '~>3.0.0' 
gem 'carrierwave-mongoid', :require => 'carrierwave/mongoid' 
gem 'mini_magick', :require => 'mini_magick' 
#... 

的lib/uploader.rb

class Uploader < CarrierWave::Uploader::Base 

    include CarrierWave::MiniMagick 

    storage :grid_fs 

    ## 
    # Directory where uploaded files will be stored (default is /public/uploads) 
    # 
    def store_dir 
    '/content/images' 
    end 

    ## 
    # Directory where uploaded temp files will be stored (default is [root]/tmp) 
    # 
    def cache_dir 
    Padrino.root("/tmp") 
    end 

    def extension_white_list 
    %w(jpg jpeg gif png) 
    end 

    ## 
    # Override the filename of the uploaded files 
    # 
    # def filename 
    # "something.jpg" if original_filename 
    # end 
end 

模型

class Thing 
    include Mongoid::Document 
    include Mongoid::Timestamps 

    field :name, :type => String 
    field :year, :type => Integer 
    #... 

    mount_uploader :picture, Uploader 
end 

控制器

YourApp::App.controllers :things do 

    get :image, with: [:id], provides: ['.jpeg', '.jpg', '.png', '.gif'] do 
    thing = Thing.find(params[:id]) 
    content_type thing.picture.content_type 
    response.write(thing.picture.read) 

    end 

    error Mongoid::Errors::MongoidError do 
    halt 404, 'File not found' 
    end 

end 

视图(HAML)

/... 
%img{:src => url_for(:things, :image, thing.id)}/ 
/... 

管理员/视图/东西/ _form.haml

/... 
%fieldset.control-group{:class => error ? 'has-error' : ''} 
    =f.label :picture, :class => 'control-label' 
    .controls 
    =f.file_field :picture, :class => 'form-control input-large input-with-feedback' 
    %span.help-inline=error ? f.error_message_on(:picture, :class => 'file-error') : pat(:example) 
/... 

谢谢@Ryan McGeary和@Darío。