validates thoughtbot rails ruby-on-rails paperclip

ruby on rails - thoughtbot - Guardar archivos usando Paperclip sin cargar



paperclip rails 5 (2)

Yo tenía una pregunta rápida. ¿Es posible guardar un archivo sin subirlo a través de un formulario?

Por ejemplo, digamos que estoy viendo archivos adjuntos de correos electrónicos y quiero guardarlos con un clip. ¿Cómo hago esto? ¿Tengo que llamar manualmente a save_file (o algo similar) en algún lugar?

¡Cualquier ayuda sería muy apreciada!


El archivo guardado en Paperclip no tiene que cargarse directamente a través de un formulario.

Estoy usando Paperclip en un proyecto para guardar archivos de las URL de los resultados del webcrawler. No estoy seguro de cómo obtendrás los archivos adjuntos del correo electrónico (¿están en el sistema de archivos local del servidor? ¿Es tu aplicación una aplicación de correo electrónico como GMail?) Pero siempre y cuando obtengas un archivo (a través de algo como open(URI.parse(crawl_result)) en mi caso ...) puede adjuntar ese archivo a su campo modelo que está marcado como has_attached_file .

Esta publicación del blog sobre Easy Upload a través de la URL con Paperclip me ayudó a resolver esto.

Dado que ahora parece que la publicación original del blog ya no está disponible, aquí está la esencia de esto extraída de la máquina de wayback:

Este ejemplo muestra un modelo de foto que tiene una imagen adjunta.

La técnica que estamos utilizando requiere agregar una *_remote_url (cadena) para su archivo adjunto, que se utiliza para almacenar la URL original. Entonces, en este caso, debemos agregar una columna llamada image_remote_url la tabla de fotos.

# 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

No se requiere nada especial para el controlador ...

# 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

En el formulario, agregamos un text_field llamado :image_url , para que las personas puedan subir un archivo o proporcionar una 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 %>

Lo sustancioso está en el modelo de Foto. Necesitamos require open-uri , agregar un attr_accessor :image_url , y hacer las cosas normales de has_attached_file . Luego, agregamos una devolución de llamada before_validation para descargar el archivo en el atributo image_url (si se proporciona) y image_remote_url URL original como image_remote_url . Finalmente, hacemos una validates_presence_of :image_remote_url , que nos permite rescatar de las muchas excepciones que pueden surgir al intentar descargar el archivo.

# 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

Todo funcionará normalmente, incluida la creación de miniaturas, etc. Además, dado que estamos haciendo todas las cosas difíciles del modelo, "cargar" un archivo a través de una URL también funciona desde el script / consola:

$ 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">


Tengo una tarea de rake que carga imágenes (logotipos de clientes) desde un directorio directamente en el parperclip. Probablemente puedas adaptarlo a tus necesidades.

Este es mi modelo de cliente simplificado:

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

Entonces en mi tarea de rastrillo hago esto:

# 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

¡Saludos!