Pregunta

Tengo un proyecto con un andamio de "artículo", que incluye un campo de archivo de clip para la miniatura, y otros en el equipo se quejan de cómo deben agregar el archivo al campo nuevamente cuando envíen el formulario y un El error de validación se activa debido a los datos faltantes en otro campo.

Figurando que se debió a las limitaciones del navegador, agregué un control remoto=> fiel al formulario, junto con un archivo ERRORTE.JS.ERB, lo que creo que el campo del archivo persistiría si la página no tenía que ser recargada. Lamentablemente, ese no fue el caso, ya que leí que los navegadores no pueden procesar formularios / archivos multiparte a través de AJAX por razones de seguridad. Sin embargo, luego descubrí el remotipart gema que resuelve este problema. Así que las partes relevantes de mi solicitud se ve como lo siguiente ...

_form.html.erb

<%= form_for(@article, :html => { :multipart => true }, :remote => TRUE) do |f| %>
  <div id="errors"></div>
  <%= f.text_field :title %>
  <%= f.text_area :body %>
  <%= f.file_field(:photo) %>
  <%= f.submit %>
<% end %>

articles_controller.rb (crear acción)

  def create
    @article = Article.new(params[:article])

    respond_to do |format|
      if @article.save
        format.html { redirect_to(@article, :notice => 'Article was successfully created.') }
        format.xml  { render :xml => @article, :status => :created, :location => @article }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @article.errors, :status => :unprocessable_entity }
        format.js { render 'errors', :locals => { :item => @article } }
      end
    end
  end

errores.js.erb

<%= remotipart_response do %>
    $("#errors").empty().append('<div id="error_explanation"><h2><%= pluralize(item.errors.count, "error") %> prohibited this article from being saved:</h2><ul></ul></div>');
    <% item.errors.full_messages.each do |msg| %>
        $("#error_explanation ul").append("<li><%= escape_javascript(msg) %></li>");
    <% end %>
<% end %>

Básicamente, si hay errores de validación, el archivo JS agrega esos errores a los errores div en el formulario. Además, el campo de archivo persiste si está lleno. Todo funciona: crea el contenido de la base de datos y cargue el archivo, o tire los errores sin perder el campo del archivo si algo falla la validación, pero queda un problema.

Cuando el formulario se envía con un archivo cargado, obtengo un error 406 no permitido en mi registro sin una redirección a la página de espectáculos. Si el formulario no tiene un archivo cargado, entonces el registro devuelve un 200 ok, pero la página tampoco se redirige a la acción Mostrar.

Después de cazar en Google y otros hilos, encontré este tipo de código que supuestamente lo pasaría los encabezados correctos (y sí, Jquery está instalado y se ejecuta antes de aplicar.js) ...

application.js

jQuery.ajaxSetup({ 
  'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")}
})

... Lamentablemente no funciona. Estoy fuera de las ideas, ¿alguna sugerencia sobre cómo superar ese número 406 y hacer esto correctamente redirigir?

¿Fue útil?

Solución 2

Haven't been able to come back to this issue until now, but I finally solved this. First off, I dropped the application.js code. Second, the 406 redirect was solved by including a format.js in the respond_to's save success...

respond_to do |format|
  if @article.save
    format.js
    format.html { [...] }
  else
    [...]
  end
end

Only issue is, the page would not redirect at all, even if a redirect_to was placed in the format.js. It did trigger a create.js.erb file, so inside of that, I put...

window.location.replace("/articles");

...to initiate the redirect upon loading create.js.erb. I would rather it respond and redirect via the controller rather than a javascript redirect, but I have yet to see a working solution to this issue (anything else I researched involving request.xhr code didn't work at all). But this works.

However, a side benefit to doing it this way is that I can get more creative with the article saving, such as previewing the 'show' page for a few seconds before redirecting to the articles index, etc.

Otros consejos

I think that you are making this too complex, why not focus on preventing the users from uploading the file again after an error in the first place. The users continue on their merry way and you don't have to mess with ugly JavaScript hacks.

Store the file and redirect the user to an the create page with the file field filled in.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top