Rails 3 выдает ajax POST, за которым следует GET на тот же URL

Как показано ниже, я в приложении Rails 3.1 пытаюсь выполнить POST с помощью link_to, используя блок:

просмотры/стена/_problem.html.erb

<li data-icon="check">
<%= link_to(
  url_for(
    :controller => 'completed_problems',
    :action => 'create',
    :problem_id => "#{problem.id}"),
  {:class => "wall_problem",
  :confirm => "Climbed it?",
  :remote => true,
  :"data-type" => "json",
  :method => "POST"}) do %>
<div>stuff</div>
<% end %>
</li>

просмотры/стена/show.html.erb

<% content_for :content do %>
  <div data-role="content">
  <ul data-role="listview">
    <%= render :partial => 'problem', :collection => @wall.live_problems.sort %>
  </ul>
<% end %>

<script>
  $('.wall_problem').live('ajax:success', function() {
    alert("Success!");
  });
</script>

Этот конкретный POST направлен на следующее действие контроллера:

контроллеры/completed_problems_controller.rb

class CompletedProblemsController < ApplicationController
  # POST /completed_problems
  def create
    @problem = Problem.find(params[:problem_id]
    @completed_problem = @problem.completed_problems.build
    if @completed_problem.save
      render :json => { }
    else
      render :json => { :location => root_url}
    end
  end
end

Как вы можете видеть из приведенных ниже журналов, POST успешно выполняется, как и должно быть, но по какой-то причине приложение одновременно выполняет GET для того же URL-адреса.

ЖУРНАЛЫ

Started POST "/completed_problems?problem_id=11" for 127.0.0.1 at 2011-12-11 13:13:06 -0500
  Processing by CompletedProblemsController#create as JSON
  Parameters: {"problem_id"=>"11"}
  # SQL stuff snipped from here
Completed 200 OK in 116ms (Views: 3.0ms | ActiveRecord: 2.6ms)

Started GET "/completed_problems?problem_id=11" for 127.0.0.1 at 2011-12-11 13:13:06 -0500
  Processing by CompletedProblemsController#index as HTML
  Parameters: {"problem_id"=>"11"}
Rendered completed_problems/index.html.erb within layouts/application (29.6ms)
Completed 500 Internal Server Error in 36ms

Проблема действительно похожа по объему на jQuery ajax POST вызывает немедленный GET для того же URL-адреса, но это использует jquery_ujs, и я не думаю, что оставил какой-либо пользовательский код jquery без дела. Таким образом, я не могу выполнить решение, предложенное в этой проблеме, с добавлением «возврата false»;

Я подозреваю, что проблема в одном из трех мест:

  1. У меня неправильный синтаксис для использования элемента link_to с блоком
  2. Моя обработка запроса в контроллере неверна
  3. Я каким-то образом удвоил свой jquery_ujs (что я действительно не думаю, что это правда, но это может быть здесь)

ИЗМЕНИТЬ

Сужение проблемы №1:

Я изменил свой сценарий на следующий,

<script>
  $('.wall_problem').live('ajax:beforeSend', function() {
    return false;
  });
</script>

И обнаружил, что POST теперь не прошел, но GET прошел, подтверждая, что проблема, по-видимому, заключается в том, что обработчик AJAX правильно берет ссылку и отправляет ее как POST, но не перехватывает GET, который отправляет браузер.

Сужение проблемы № 2:

Сначала я не упомянул об этом, но я использую Jquery-mobile. Теперь, восстанавливая тег script в его прежней форме, а затем отключая jquery-mobile, я снова попробовал ссылку, и теперь он не отправляет GET, но отправляет POST. Это наводит меня на мысль, что есть некоторая проблема с тем, как jquery-ujs и jquery mobile взаимодействуют со ссылкой.


person IanWhalen    schedule 11.12.2011    source источник
comment
Есть ли у одной проблемы много выполненных_проблем? Или задача завершена или не завершена. Если это будет позже, у меня просто будет логическое значение в таблице Post, чтобы сказать, было ли оно завершено или нет. Затем вы можете просто сделать простой AJAX-вызов действия update tasks_controller и установить для свойства Completed значение ture или false. Я не уверен, так ли построено ваше приложение, но если это так, я отправляю ответ о том, как вы можете это решить.   -  person Andreas Lyngstad    schedule 12.12.2011
comment
Объект CompletedProblem фактически является объектом соединения между пользователем и проблемой, поэтому я не думаю, что это поможет. Выполнение этого также кажется, что это было бы просто решением более крупной проблемы.   -  person IanWhalen    schedule 12.12.2011
comment
Если у пользователя есть_много проблем и проблема принадлежит пользователю, вам не нужно присоединение. С помощью простого логического поля вы можете создавать такие области видимости, как user.problems.where(:completed => false). Это не вариант обходного пути. Более простой код => меньше проблем. Кроме того, вы можете написать собственную функцию Jquery для обработки AJAX POST, а затем в ответ обновить свое представление с помощью шаблона .js.erb.   -  person Andreas Lyngstad    schedule 12.12.2011


Ответы (1)


Основываясь на информации, которую я включил в приведенное выше редактирование, я продолжил тестирование Jquery Mobile и смог решить.

Сначала я обновился до Jquery Mobile v1.0, который добавил глобальную конфигурацию linkBindingEnabled (http://jquerymobile.com/demos/1.0/docs/api/globalconfig.html):

Во-вторых, я установил для этой конфигурации значение False:

$(document).bind("mobileinit", function(){
  $.mobile.linkBindingEnabled = false;
});
person IanWhalen    schedule 12.12.2011