Pergunta

Eu tenho um projeto com um "Artigo" scaffold, que inclui um clipe campo arquivo de miniatura e outros na equipe estão reclamando sobre como eles têm para adicionar o arquivo para o campo novamente ao enviar o formulário e um erro de validação é acionado devido à falta de dados em outro campo.

Descobrir que foi devido a limitações de navegador, eu adicionei um remote => true para o formulário, juntamente com um erro.js.erb arquivo, calculando o campo do arquivo que persistem se a página não precisa ser recarregado.Infelizmente não foi o caso, como eu li que os navegadores são capazes de processar formulários multiparte / arquivos através de AJAX por razões de segurança.No entanto, descobri então o Remotipart gem que resolve este problema.Assim, as partes relevantes da minha aplicação tem o seguinte aspecto...

_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 (Criar uma ação)

  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

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

Então, basicamente, se há erros de validação, o arquivo js adiciona os erros os erros div no formulário.Além disso, o arquivo de campo persistir se preenchido.Tudo funciona:ele NÃO cria o conteúdo do banco de dados e fazer o upload do arquivo, OU jogar até os erros, sem perder o arquivo de campo se algo falha de validação, mas um problema permanece.

Quando o formulário é enviado com um arquivo carregado, eu recebo um 406 não é permitido o erro no meu log sem um redirecionamento para a página do show.Se o formulário NÃO tem um arquivo carregado, o log retorna um 200 OK, mas a página também não é redirecionada para a action show.

Após a caça no Google e outras threads, eu encontrei este pedaço de código que supostamente iria passá-lo a corrigir os cabeçalhos (e sim, jQuery é instalado e é executado antes de application.js)...

application.js

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

...infelizmente ele não funciona.Estou sem ideias, sugestões sobre como vencer a 406 problema e fazer isso corretamente redirecionamento?

Foi útil?

Solução 2

Não tenho sido capaz de voltar a esta questão até agora, mas eu finalmente resolvido isso.Primeiro, eu deixei cair o application.js código.Segundo, a 406 redirecionar foi resolvido com a inclusão de um format.js no respond_to salvar o sucesso...

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

Único problema é, a página de redirecionamento não em tudo, mesmo se um redirect_to foi colocado na format.js.Ele fez desencadear um criar.js.erb arquivo, portanto, dentro do que eu coloquei...

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

...para iniciar o redirecionamento após o carregamento de criar.js.erb.Eu prefiro ele responder e redirecionar através do controlador, ao invés de incluir um redirecionamento javascript, mas ainda estou para ver uma solução para este problema (coisa que eu pesquisei envolvendo pedido.xhr código não funciona em todos).Mas isso funciona.

No entanto, uma vantagem para fazê-lo desta maneira é que eu posso ser mais criativo com o artigo de verão, tais como visualização de 'mostrar' a página por alguns segundos antes de redirecionar para o índice de artigos, etc.

Outras dicas

Eu acho que você está fazendo isso muito complexa, por que não concentrar-se em evitar que os usuários fazer o upload do arquivo novamente após um erro em primeiro lugar.Os usuários continuam em sua feliz e você não tem que mexer com o feio JavaScript hacks.

Armazenar o arquivo e redirecionar o usuário para uma página criar o arquivo de campo preenchido.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top