簡単な質問がありました。フォームから実際にアップロードせずにファイルを保存することはできますか?
たとえば、電子メールの添付ファイルを見ていて、ペーパークリップを使用してそれらを保存したいとします。どうすればよいですか?どこかでsave_file(または同様のもの)を手動で呼び出す必要がありますか?
どんな助けでも大歓迎です!
ディレクトリから直接parperclipに画像(クライアントロゴ)をロードするrakeタスクがあります。あなたはおそらくそれをあなたのニーズに適応させることができます。
これは私の単純化されたクライアントモデルです:
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
よろしく!
Paperclipに保存されたファイルは、フォームから直接アップロードする必要はありません。
プロジェクトでPaperclipを使用して、webcrawlerの結果のURLからファイルを保存しています。メールの添付ファイルをどのように取得するかはわかりませんが(サーバーのローカルファイルシステムにありますか?アプリはGMailのようなメールアプリですか?)、ファイルストリームを取得できる限り(open(URI.parse(crawl_result))
私の場合...)has_attached_file
とマークされたモデルフィールドにそのファイルを添付できます。
Paperclipを使用したURL経由の簡単なアップロード に関するこのブログ投稿は、これを理解するのに役立ちました。
元のブログ投稿は利用できなくなったようです。ウェイバックマシンから取得した要点は次のとおりです。
この例は、画像が添付された写真モデルを示しています。
私たちが使用している手法では、添付ファイルに*_remote_url
(文字列)列を追加する必要があります。これは、元のURLを格納するために使用されます。したがって、この場合、image_remote_url
photosテーブルという名前の列を追加する必要があります。
# 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
フォームに: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 %>
肉のようなものは写真モデルにあります。 require open-uri
を実行し、attr_accessor :image_url
を追加して、通常のhas_attached_file
を実行する必要があります。次に、before_validation
コールバックを追加して、ファイルをimage_url
属性(提供されている場合)にダウンロードし、元のURLをimage_remote_url
として保存します。最後に、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
サムネイルの作成など、すべてが通常どおり機能します。さらに、モデル内のすべての難しい作業を行っているため、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">