[英]Saving files using Paperclip without upload
I had a quick question. 我有一个简短的问题。 Is it possible to save a file without actually uploading it through a form?
是否可以保存文件而不通过表单实际上传?
For example, let's say I'm looking at attachments from emails, and I want to save them using a paperclip. 例如,假设我正在查看电子邮件中的附件,我想使用回形针保存它们。 How do I do this?
我该怎么做呢? Do I manually have to call a save_file(or something similar) somewhere?
我是否需要在某处手动调用save_file(或类似的东西)?
Any help would be much appreciated! 任何帮助将非常感激!
I have a rake task that loads images (client logos) from a directory directly onto parperclip. 我有一个rake任务,可以将目录中的图像(客户端徽标)直接加载到parperclip上。 You can probably adapt it to your needs.
您可以根据自己的需要进行调整。
This is my simplified Client model: 这是我简化的客户端模型:
class Client < ActiveRecord::Base
LOGO_STYLES = {
:original => ['1024x768>', :jpg],
:medium => ['256x192#', :jpg],
:small => ['128x96#', :jpg]
}
has_attached_file :logo,
:styles => Client::LOGO_STYLES,
:url => "/clients/logo/:id.jpg?style=:style"
attr_protected :logo_file_name, :logo_content_type, :logo_size
Then on my rake task I do this: 然后我的rake任务我这样做:
# the logos are in a folder with path logos_dir
Dir.glob(File.join(logos_dir,'*')).each do |logo_path|
if File.basename(logo_path)[0]!= '.' and !File.directory? logo_path
client_code = File.basename(logo_path, '.*') #filename without extension
client = Client.find_by_code(client_code) #you could use the ids, too
raise "could not find client for client_code #{client_code}" if client.nil?
File.open(logo_path) do |f|
client.logo = f # just assign the logo attribute to a file
client.save
end #file gets closed automatically here
end
end
Regards! 问候!
The file saved in Paperclip doesn't have to be uploaded directly through a form. 保存在Paperclip中的文件不必直接通过表单上传。
I'm using Paperclip in a project to save files from URLs from webcrawler results. 我在项目中使用Paperclip来保存来自webcrawler结果的URL中的文件。 I'm not sure how you'd get email attachments (are they on the local file system of the server? Is your app an email app like GMail?) but as long as you can get a file stream (via something like
open(URI.parse(crawl_result))
in my case...) you can attach that file to your model field that's marked has_attached_file
. 我不确定你是如何获得电子邮件附件的(他们是否在服务器的本地文件系统上?你的应用程序是一个像GMail这样的电子邮件应用程序吗?)但只要你能得到一个文件流(通过像
open(URI.parse(crawl_result))
这样的东西) open(URI.parse(crawl_result))
在我的情况下...)您可以将该文件附加到标记为has_attached_file
模型字段。
This blog post about
Easy Upload via URL with Paperclip helped me figure this out.
这篇关于
通过URL与Paperclip轻松上传的博客文章帮助我解决了这个问题。
Since it now appears the original blog post is no longer available - here's the gist of it pulled from wayback machine: 既然现在看来原来的博客文章已经不再可用了 - 这里是它从回归机器中拉出来的要点:
This example shows a Photo model that has an Image attachment. 此示例显示具有图像附件的Photo模型。
The technique we're using requires adding a *_remote_url
(string) column for your attachment, which is used to store the original URL. 我们使用的技术要求为附件添加
*_remote_url
(字符串)列,用于存储原始URL。 So, in this case, we need to add a column named image_remote_url
the photos table. 因此,在这种情况下,我们需要在照片表中添加名为
image_remote_url
的列。
# db/migrate/20081210200032_add_image_remote_url_to_photos.rb
class AddImageRemoteUrlToPhotos < ActiveRecord::Migration
def self.up
add_column :photos, :image_remote_url, :string
end
def self.down
remove_column :photos, :image_remote_url
end
end
Nothing special is required for the controller... 控制器没有什么特别之处......
# app/controllers/photos_controller.rb
class PhotosController < ApplicationController
def create
@photo = Photo.new(params[:photo])
if @photo.save
redirect_to photos_path
else
render :action => 'new'
end
end
end
In the form, we add a text_field called :image_url
, so people can upload a file or provide a URL... 在表单中,我们添加了一个名为
:image_url
的text_field,因此人们可以上传文件或提供URL ...
# app/views/photos/new.html.erb
<%= error_messages_for :photo %>
<% form_for :photo, :html => { :multipart => true } do |f| %>
Upload a photo: <%= f.file_field :image %><br>
...or provide a URL: <%= f.text_field :image_url %><br>
<%= f.submit 'Submit' %>
<% end %>
The meaty stuff is in the Photo model. 多肉的东西在Photo模型中。 We need to
require open-uri
, add an attr_accessor :image_url
, and do the normal has_attached_file
stuff. 我们需要
require open-uri
,添加一个attr_accessor :image_url
,然后执行正常的has_attached_file
。 Then, we add a before_validation
callback to download the file in the image_url
attribute (if provided) and save the original URL as image_remote_url
. 然后,我们添加一个
before_validation
回调来下载image_url
属性中的文件(如果提供)并将原始URL保存为image_remote_url
。 Finally, we do a validates_presence_of :image_remote_url
, which allows us to rescue from the many exceptions that can be raised when attempting to download the file. 最后,我们执行
validates_presence_of :image_remote_url
,它允许我们从尝试下载文件时可能引发的许多异常中解救出来。
# app/models/photo.rb
require 'open-uri'
class Photo < ActiveRecord::Base
attr_accessor :image_url
has_attached_file :image # etc...
before_validation :download_remote_image, :if => :image_url_provided?
validates_presence_of :image_remote_url, :if => :image_url_provided?, :message => 'is invalid or inaccessible'
private
def image_url_provided?
!self.image_url.blank?
end
def download_remote_image
self.image = do_download_remote_image
self.image_remote_url = image_url
end
def do_download_remote_image
io = open(URI.parse(image_url))
def io.original_filename; base_uri.path.split('/').last; end
io.original_filename.blank? ? nil : io
rescue # catch url errors with validations instead of exceptions (Errno::ENOENT, OpenURI::HTTPError, etc...)
end
end
Everything will work as normal, including the creation of thumbnails, etc. Plus, since we're doing all of the hard stuff in the model, "uploading" a file via URL works from within script/console as well: 一切都会正常工作,包括创建缩略图等。此外,由于我们正在模拟模型中的所有硬件,因此通过URL“上传”文件也可以在脚本/控制台中工作:
$ script/console
Loading development environment (Rails 2.2.2)
>> Photo.new(:image_url => 'http://www.google.com/intl/en_ALL/images/logo.gif')
=> #<Photo image_file_name: "logo.gif", image_remote_url: "http://www.google.com/intl/en_ALL/images/logo.gif">
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.