Domanda

Ho un progetto con un impalcatura "Articolo" - che include un campo di file PaperClip per la miniatura - e altri sul team si lamentano di come devono aggiungere il file al campo quando inviano il modulo e un L'errore di convalida viene attivato a causa di dati mancanti su un altro campo.

La creazione di limitazioni del browser, ho aggiunto un telecomando=> VERO al modulo, insieme a un file ERROR.JS.ERB, che capisce il campo del file persistere se la pagina non deve essere ricaricata. Purtroppo non è stato il caso, come ho letto che i browser non sono in grado di elaborare moduli / file multipart attraverso Ajax per motivi di sicurezza. Tuttavia, ho scoperto il remotipart gem che risolve questo problema. Quindi le parti pertinenti della mia applicazione sembrano il seguente ...

_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 (creare azione)

  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
.

errors.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 %>
.

Così fondamentalmente, se ci sono errori di convalida, il file JS aggiunge tali errori agli errori div sul modulo. Inoltre, il campo File persiste se compilato. Tutto funziona: crea il contenuto nel database e caricamento del file o si collega gli errori senza perdere il campo del file se qualcosa non riesce a convalidare, ma rimane un problema. .

Quando il modulo viene inviato con un file caricato, ottengo un errore 406 non consentito nel mio registro senza reindirizzamento alla pagina Mostra. Se il modulo non ha un file caricato, il registro restituisce un 200 ok, ma anche la pagina non viene reindirizzata nell'azione Mostra.

Dopo aver cacciare Google e altri thread, ho trovato questo pezzo di codice che presumibilmente passerà le intestazioni corrette (e sì, jquery è installato e viene eseguito prima dell'applicazione.js) ...

application.js

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

... Purtroppo non funziona. Sono fuori di idee, qualsiasi suggerimento su come battere quel problema 406 e renderlo correttamente reindirizzamento?

È stato utile?

Soluzione 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.

Altri suggerimenti

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top