Ruby on Rails: обнаружение ошибки 406 / отсутствие перенаправления с помощью формы AJAXified - PullRequest
0 голосов
/ 18 мая 2011

У меня есть проект с шаблоном «Article», который включает в себя поле файла скрепки для миниатюры, и другие члены команды жалуются на то, что им нужно снова добавить файл в поле, когда они отправляют форму и Ошибка проверки вызвана отсутствием данных в другом поле.

Исходя из ограничений браузера, я добавил к форме remote => true вместе с файлом error.js.erb, чтобы выяснить, будет ли сохранено поле файла, если страница не будет перезагружаться. К сожалению, это было не так, поскольку я прочитал, что браузеры не могут обрабатывать составные формы / файлы через AJAX по соображениям безопасности. Однако затем я обнаружил Remotipart gem , который решает эту проблему. Таким образом, соответствующие части моего приложения выглядят следующим образом ...

_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 %>

article_controller.rb (Создать действие)

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

Таким образом, в основном, если есть ошибки проверки, файл js добавляет эти ошибки в div ошибок в форме. Кроме того, поле файла сохраняется, если оно заполнено. Все работает: оно создает содержимое в базе данных и загружает файл, ИЛИ выдает ошибки, не теряя поле файла, если что-то не проходит проверку, но остается одна проблема.

Когда форма отправляется с загруженным файлом, в моем журнале появляется ошибка 406 без разрешения без перенаправления на страницу показа. Если в форме НЕ загружен файл, журнал возвращает 200 OK, но страница также не перенаправлена ​​на действие show.

После поиска в Google и других SO-потоках я обнаружил этот фрагмент кода, который предположительно передал бы ему правильные заголовки (и да, jQuery установлен и запускается до application.js) ...

application.js

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

... к сожалению, это не работает. У меня нет идей, есть ли какие-либо предложения о том, как решить эту проблему 406 и сделать ее правильно перенаправленной?

Ответы [ 2 ]

0 голосов
/ 19 июля 2011

До сих пор не удавалось вернуться к этой проблеме, но я наконец решил это. Во-первых, я сбросил код application.js. Во-вторых, перенаправление 406 было решено включением файла format.js в успешное сохранение файла response_to ...

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

Единственная проблема в том, что страница не будет перенаправлена ​​вообще, даже если redirect_to был помещен в format.js. Он запустил файл create.js.erb, поэтому внутри я поместил ...

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

... чтобы инициировать перенаправление при загрузке create.js.erb. Я бы предпочел, чтобы он отвечал и перенаправлял через контроллер, а не через javascript-редирект, но мне еще предстоит увидеть работающее решение этой проблемы (все остальное, что я исследовал, включая код request.xhr, вообще не работало). Но это работает.

Тем не менее, побочным преимуществом такого подхода является то, что я могу проявить больше творческого подхода к сохранению статьи, например, просмотреть страницу «show» за несколько секунд до перенаправления на индекс статей и т. Д.

0 голосов
/ 18 мая 2011

Я думаю, что вы делаете это слишком сложным, почему бы не сосредоточиться на том, чтобы не дать пользователям снова загрузить файл после ошибки в первую очередь. Пользователи продолжают свой веселый путь, и вам не нужно возиться с уродливыми взломами JavaScript.

Сохраните файл и перенаправьте пользователя на страницу создания с заполненным полем файла.

...