使用Paperclip保存文件而不上传

时间:2009-11-03 11:29:48

标签: ruby-on-rails paperclip

我有一个简短的问题。是否可以保存文件而不通过表单实际上传?

例如,假设我正在查看电子邮件中的附件,我想使用回形针保存它们。我该怎么做呢?我是否需要在某处手动调用save_file(或类似的东西)?

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:47)

我有一个rake任务,可以将目录中的图像(客户端徽标)直接加载到parperclip上。你可以根据自己的需要调整它。

这是我简化的客户端模型:

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

然后在我的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

问候!

答案 1 :(得分:11)

Paperclip中保存的文件无需直接通过表单上传。

我在项目中使用Paperclip来保存来自webcrawler结果的URL中的文件。我不确定你是如何获得电子邮件附件的(它们是否在服务器的本地文件系统上?你的应用程序是否像GMail一样是电子邮件应用程序?)但只要你能获得文件流(通过像{{ 1}}在我的情况下...)您可以将该文件附加到标记为open(URI.parse(crawl_result))的模型字段中。

这篇关于Easy Upload via URL with Paperclip的博文帮助我解决了这个问题。

因为它现在看来原来的博客文章已经不再可用 - 这里是它从回归机器中提取的要点:

此示例显示具有图像附件的Photo模型。

我们使用的技术要求为附件添加has_attached_file(字符串)列,用于存储原始网址。因此,在这种情况下,我们需要在照片表中添加名为*_remote_url的列。

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

在表单中,我们添加了一个名为# 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 的text_field,以便人们可以上传文件或提供网址...

:image_url

肉类的东西在Photo模型中。我们需要# 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 %> ,添加require open-uri,并执行正常的attr_accessor :image_url内容。然后,我们添加has_attached_file回调以下载before_validation属性(如果提供)中的文件,并将原始网址保存为image_url。最后,我们执行了image_remote_url,它允许我们从尝试下载文件时可以引发的许多异常中解脱出来。

validates_presence_of :image_remote_url

一切都会正常工作,包括创建缩略图等。此外,由于我们正在模拟模型中的所有硬件,因此通过URL“上传”文件也可以在脚本/控制台中工作:< / p>

# 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