2012-04-27 7 views
6

Quiero crear un registro de usuario de 3 pasos con carga de avatar en el 2do paso. Entonces sigo la guía de Ryan Bates http://railscasts.com/episodes/217-multistep-forms. Estoy usando la gema CarrierWave para manejar las cargas. Pero parece que no puedo almacenar la información del archivo cargado en la sesión del usuario (estoy obteniendo no puedo volcar el error del archivo). Yo uso la siguiente técnica en el controladorFormulario de pasos múltiples con cargador de imágenes

En realidad ayuda. Pero cuando subo accidentes prohibido todo tipo de archivo de esta línea

@uploader.store!(params[:user][:img_path]) 

con este error

CarrierWave::IntegrityError in UsersController#create 
You are not allowed to upload "docx" files, allowed types: ["jpg", "jpeg", "gif", "png"] 

en lugar de errores normal de validación de formularios.

¿Cómo puedo resolver este problema? Gracias !

+0

¿de verdad está cargando un archivo de imagen o un archivo de palabra de Microsoft? –

+0

necesito validar el tipo de archivo antes de cargarlo – AlphaB

+0

Debería capturar el 'CarrierWave :: IntegrityError' o usar el método' store() '(without!), Para que no arroje el error. –

Respuesta

3

En realidad, he resuelto mi problema. Aquí está el código de trabajo para las formas de varios pasos con la carga de archivos utilizando carrierwave

if params[:user][:img_path] 
    @uploaded = params[:user][:img_path] 
    params[:user].delete(:img_path) 
end 
session[:user_data].deep_merge!(params[:user]) if params[:user] 
@user = User.new(session[:user_data])  

if @uploaded 
    # here how validation will work 
    @user.img_path = @uploaded 
end 
@user.current_stage = session[:register_stage] 
if @user.valid? 
    if @user.last_stage? 
    @user.img_path = session[:img] if @user.last_stage? 
    @user.save 
    else 
    @user.next_stage 
    end 
    # now we can store carrierwave object in session 
    session[:img] = @user.img_path 
    session[:register_stage] = @user.current_stage 
end 
+0

¡Felicidades por la solución!Cuando pueda, asegúrese de marcar su respuesta como 'aceptada' para que otros puedan aprender de su éxito. Saludos ~ –

1

Esto puede ser un poco tarde para el PO, pero espero que esto ayude a alguien. Necesitaba almacenar una imagen cargada en la sesión del usuario (nuevamente para un formulario de varios pasos), y también comencé con la Railscast #217 de Ryan, pero la aplicación evolucionó rápidamente más allá de eso. Tenga en cuenta que mi entorno era Rails 4 en Ruby 2, utilizando Carrierwave y MiniMagick, así como activerecord-session_store, que explicaré a continuación.

Creo que el problema que tenía OP y yo era que estábamos tratando de agregar todos los parámetros de POST a la sesión del usuario, pero con una carga de archivos, uno de los parámetros era un objeto UploadedFile real, que es a lo grande por eso. El enfoque que se describe a continuación es otra solución a ese problema.

Descargo de responsabilidad: Como es ampliamente notado, no es ideal almacenar objetos complejos en una sesión de usuario, mejor almacenar identificadores de registro u otros datos identificadores (por ejemplo, la ruta de una imagen) y buscar esos datos cuando sea necesario. Dos razones principales para mantener la sesión y los datos de la base de datos/modelo en sincronía (una tarea no trivial), y el almacenamiento de sesión de Rails por defecto (usando cookies) están limitados a 4kb.

mi modelo (submission.rb):

class Submission < ActiveRecord::Base 
    mount_uploader :image_original, ImageUploader 
    # ... 
end 

Controlador (submissions_controller.rb):

def create 
    # If the submission POST contains an image, set it as an instance variable, 
    # because we're going to remove it from the params 
    if params[:submission] && params[:submission][:image_original] && !params[:submission][:image_original].is_a?(String) 
    # Store the UploadedFile object as an instance variable 
    @image = params[:submission][:image_original] 
    # Remove the uploaded object from the submission POST params, since we 
    # don't want to merge the whole object into the user's session 
    params[:submission].delete(:image_original) 
    end 

    # Merge existing session with POST params 
    session[:submission_params].deep_merge!(params[:submission]) if params[:submission] 

    # Instantiate model from newly merged session/params 
    @submission = Submission.new(session[:submission_params]) 
    # Increment the current step in the session form 
    @submission.current_step = session[:submission_step] 

    # ... other steps in the form 

    # After deep_merge, bring back the image 
    if @image 
    # This adds the image back to the Carrierwave mounted uploader (which 
    # re-runs any processing/versions specified in the uploader class): 
    @submission.image_original = @image 
    # The mounted uploader now has the image stored in the Carrierwave cache, 
    # and provides us with the cache identifier, which is what we will save 
    # in our session: 
    session[:submission_params][:image_original] = @submission.image_original_cache 
    session[:image_processed_cached] = @submission.image_original.url(:image_processed) 
    end 

    # ... other steps in the form 

    # If we're on the last step of the form, fetch the image and save the model 
    if @submission.last_step? 
    # Re-populate the Carrierwave uploader's cache with the cache identifier 
    # saved in the session 
    @submission.image_original_cache = session[:submission_params][:image_original] 
    # Save the model 
    @submission.save 
    # ... render/redirect_to ... 
    end 
end 

Mi cargador de archivos se abastecerse en su mayoría con algún tipo de procesamiento personalizado.

Nota: para reforzar las sesiones, estoy usando activerecord-session_store, que es una joya extraída del núcleo de Rails en v4 que proporciona un almacén de sesión respaldado por la base de datos (aumentando así el límite de 4kb de sesión). Siga the documentation para las instrucciones de instalación, pero en mi caso fue bastante rápido y sencillo configurarlo y olvidarlo. Nota para los usuarios con mucho tráfico: los registros de la sesión sobrante no parecen estar purgados por la gema, por lo que si obtiene suficiente tráfico, esta tabla podría llegar a innumerables filas.

+0

Estaba enfrentando el mismo problema. Solución simple. Gracias – Anwar

Cuestiones relacionadas