简体   繁体   English

使用Paperclip保存文件而不上传

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM