Ruby on Rails 上传图片
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1857187/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Uploading Pictures Ruby on Rails
提问by bgadoci
I am new to rails so sorry if this is easy. I am wondering the best way to upload pictures and display them in Ruby on Rails. I have a blog and would like to have the option of attaching a picture when creating a post.
我是 Rails 的新手,如果这很容易,我很抱歉。我想知道上传图片并在 Ruby on Rails 中显示它们的最佳方式。我有一个博客,希望在创建帖子时可以选择附加图片。
采纳答案by danpickett
Paperclip is quite awesome. There's an excellent RailsCast about it - http://railscasts.com/episodes/134-paperclip
回形针非常棒。有一个关于它的优秀 RailsCast - http://railscasts.com/episodes/134-paperclip
回答by Felipe Cerda
CarrierWave is a newer gem than Paperclip, and it looks a lot more flexible. There's also a Railscast about it: http://railscasts.com/episodes/253-carrierwave-file-uploads
CarrierWave 是比 Paperclip 更新的宝石,它看起来更加灵活。还有一个关于它的 Railscast:http://railscasts.com/episodes/253-carrierwave-file-uploads
回答by JRL
Assuming you don't need fancy features, don't wish to add a dependency and want to store the image as a BLOB in your DB, you can do something like:
假设您不需要花哨的功能,不希望添加依赖项并希望将图像作为 BLOB 存储在您的数据库中,您可以执行以下操作:
Model:
模型:
class Image < ActiveRecord::Base
def img=(input_data)
self.filename = input_data.original_filename
self.filetype = input_data.content_type.chomp
self.img = input_data.read
end
end
Controller:
控制器:
class ImagesController < ApplicationController
def display_img
@img = Image.find(params[:id])
send_data(@img.img, :type => @img.filetype, :filename => @img.filename,
:disposition => 'inline')
end
end
Here's a linkto a more complete tutorial.
回答by NoDisplayName
Many recommend to use Carrierwaveand I am not an exception but I wanted to point one thing out. On many sites written with RoR (it's obviously not only RoR issue though) I notice that the request that's sending the picture can be pending for like 2-3 secs and often even more which ties up the application instance (which is probably not that terrible if you're using threads or don't care much about performance but it definitely is if you're using unicorn). So I'll explain how to avoid that using carrierwave:
许多人推荐使用Carrierwave,我也不例外,但我想指出一件事。在许多用 RoR 编写的网站上(虽然这显然不仅仅是 RoR 问题)我注意到发送图片的请求可能会挂起 2-3 秒,甚至更多,这会占用应用程序实例(这可能不是那么糟糕)如果您正在使用线程或不太关心性能,但如果您使用的是独角兽,那肯定是这样)。所以我将解释如何使用载波来避免这种情况:
1) Pick some background worker for your app (I usually go with Sidekiq)
1)为你的应用选择一些后台工作人员(我通常使用 Sidekiq)
2) Add carrierwave_backgrounderto your Gemfile and configure it to work with your background worker and carrierwave (everything in its readme)
2) 添加carrierwave_backgrounder到您的 Gemfile 并将其配置为与您的后台工作人员和carrierwave 一起使用(自述文件中的所有内容)
I usually have control over my directories so I go with store_in_backgroundoption of carrierwave_backgrounderwhich processes and stores the picture in the file system or S3 or whatever you're using
我通常可以控制我的目录,因此我可以store_in_background选择carrierwave_backgrounder哪些进程并将图片存储在文件系统或 S3 或您正在使用的任何文件中
3) Now, when you update the picture, its processing and storing goes to background , which frees your application instance but it takes a while, in most cases more than 1 second, and you need to return some response to the user
3)现在,当您更新图片时,它的处理和存储转到后台,这会释放您的应用程序实例,但需要一段时间,在大多数情况下超过 1 秒,您需要向用户返回一些响应
4) The easiest way to provide user with some response is to return javascript in which you change the old picture to a gif with a spinner or something like that and set javascript SetIntervalfunction that checks if the picture has been processed (carrierwave_backgroundprovides a function that can change the boolean column of your model to true when it's done processing) sending AJAXrequest every 2 seconds or whatever you prefer and change the picture when it's been processed.
4) 为用户提供一些响应的最简单方法是返回 javascript,在其中您将旧图片更改为带有微调器或类似工具的 gif 并设置 javascriptSetInterval函数来检查图片是否已被处理(carrierwave_background提供一个可以完成处理后将模型的布尔列更改为 true)AJAX每 2 秒或您喜欢的任何发送请求,并在处理后更改图片。
Now you have an untied application instance and a fine user experience at the same time.
现在,您同时拥有一个未绑定的应用程序实例和良好的用户体验。
PS I am new to rails and web development per se so this guide may have some caveats that I've missed
PS 我本身是 Rails 和 Web 开发的新手,所以本指南可能有一些我遗漏的注意事项
Hope it'll help somebody.
希望它会帮助某人。
Oh, and by the way, there's this new gem called refile, it's amazing and can be a really good option in some cases.
哦,顺便说一下,有一个名为 的新宝石refile,它很棒,在某些情况下可能是一个非常好的选择。
回答by Cloudinary
CarrierWave is probably the best solution for picture uploading in Rails. The following post describes a solution for image uploading using CarrierWave while image transformations are done seamlessly in the cloud. Uploaded images are stored in the cloud and delivered through a CDN. No need to install RMagick, MiniMagick and ImageMagick. http://cloudinary.com/blog/ruby_on_rails_image_uploads_with_carrierwave_and_cloudinary
CarrierWave 可能是 Rails 中图片上传的最佳解决方案。下面的文章描述了一种使用 CarrierWave 上传图像的解决方案,同时图像转换在云中无缝完成。上传的图像存储在云端并通过 CDN 交付。无需安装 RMagick、MiniMagick 和 ImageMagick。 http://cloudinary.com/blog/ruby_on_rails_image_uploads_with_carrierwave_and_cloudinary
回答by Joshua Partogi
回答by samg
attachment_fu (http://github.com/technoweenie/attachment_fu) is another option although I personally would recommend paperclip. It doesn't require Rmagick which is a big plus, and it supports some cool features like uploads to S3 with minor configuration.
attachment_fu( http://github.com/technoweenie/attachment_fu) 是另一种选择,虽然我个人会推荐回形针。它不需要 Rmagick,这是一个很大的优势,它支持一些很酷的功能,比如只需少量配置就可以上传到 S3。
回答by Ahmed Elkoussy
Updated at August 2019
2019 年 8 月更新
For anyone checking this question recently, Rails 5.2+ now has ActiveStorage by default & I highly recommend checking it out.
对于最近检查此问题的任何人,Rails 5.2+ 现在默认具有 ActiveStorage,我强烈建议您检查一下。
Since it is part of the core Rails 5.2+ now, it is very well integrated & has excellent capabilities out of the box (still all other well-known gems like Carrierwave, Shrine, paperclip,... are great but this one offers very good features that we can consider for any new Rails project)
由于它现在是核心 Rails 5.2+ 的一部分,因此它集成得非常好并且开箱即用具有出色的功能(还有所有其他著名的宝石,如 Carrierwave、Shrine、回形针……都很棒,但这个提供了非常我们可以为任何新的 Rails 项目考虑的好特性)
Paperclip team deprecated the gem in favor of the Rails ActiveStorage.
Paperclip 团队弃用了 gem 以支持 Rails ActiveStorage。
Here is the github page for the ActiveStorage& plenty of resources are available everywhere
这是 ActiveStorage 的 github 页面,到处都有大量资源
Important note
重要的提示
Please note that some advanced features are not available in ActiveStorage, but if your use case is simple, it can be one of the easiest uploading gems to install & integrate with 3rd party cloud storage (s3, digital ocean spaces, ....)
请注意,ActiveStorage 中不提供某些高级功能,但如果您的用例很简单,它可能是最容易安装和集成 3rd 方云存储(s3、数字海洋空间……)
One of the main drawbacks for example, is that you can't define paths for your uploads in ActiveStorage, there is a hack to do that, so that each environment will upload to a different path (but still that was a big annoyance for me)
例如,主要缺点之一是您无法在 ActiveStorage 中为上传定义路径,有一个 hack 可以做到这一点,因此每个环境都将上传到不同的路径(但这对我来说仍然是一个很大的烦恼)
If your upload needs more flexibility & advanced features, I recommend checking out Shrine
如果您的上传需要更多的灵活性和高级功能,我建议您查看 Shrine
Shrine comparison with other gems, as per their official page

