Rails изменяет логическое значение с помощью флажка и jquery ajax

Я новичок в rails и пытаюсь изменить значение логического элемента с помощью флажка и с помощью jquery ajax:

<%- @tasks.each do |task| %>
  <div class="task-wrapper">
    <%= check_box_tag 'completed', task.id , task.completed, :class => "task-check" %>
    <%= content_tag :span, task.task %>
    <%= content_tag :span, task.deadline %>
  </div>
<% end %>

и javascript:

$(".task-check").bind('change', function(){
  if (this.checked){
    var bool = this.checked ? 1 : 0;
    $.ajax({
      url: '/todos/toggle',
      type: 'POST',
      data: '{"task_id":"'+ this.value +'", "bool":"'+ bool +'"}'
    });
  }
  else {
    alert("no");
  }
});

то контроллер:

def toggle(task_id, bool)
  @task = Todo.find_by_id(task_id)

  if @task != nil?
    @task.update_attributes(:completed => bool)
  else
    set_flash "Error, please try again"
  end
end

наконец, маршруты:

resources :todos do
  member do
    post 'toggle'
  end
end

также попытался собрать, но дал ту же ошибку.

когда я пытаюсь это сделать, я получаю 404 error в действии.

в чем проблема?

спасибо

Ответ 1

Попробуйте следующее (оставив все остальное как есть):

javascript:

$(".task-check").bind('change', function(){
  if (this.checked){
    $.ajax({
      url: '/todos/'+this.value+'/toggle',
      type: 'POST',
      data: {"completed": this.checked}
    });
  }
  else {
     alert("no");
  }
});

контроллер:

def toggle
  @task = Todo.find(params[:id])

  if @task.update_attributes(:completed => params[:completed])
    # ... update successful
  else
    # ... update failed
  end
end

Взгляните на bundle exec rake routes, чтобы показать вам пути, которые генерируют рельсы. В случае вашего post 'toggle', который является членом, вы получаете путь как /todos/:id/toggle, следовательно, обновленный url в ajax.

В контроллере :id от пути заканчивается на params[:id]. Данные из запроса ajax также заканчиваются хешем params, следовательно params[:completed].

Ответ 2

Как и в Rails 4, есть способ сделать это без каких-либо дополнительных JS или CSS:

<%= check_box_tag 'completed', task.id, task.completed,
      data: {
        remote: true,
        url: url_for(action: :toggle, id: task.id),
        method: "POST"
      } %>

Оказывается, добавление remote: true к вводу приводит к тому, что jquery-ujs делает его ajax-y всеми хорошими способами. Thoughtbot "Обзор Rails jQuery UJS" кратко затрагивает это (и многие другие хорошие вещи); "Ненавязчивая поддержка скриптов для jQuery" страницы в wiki jQuery UJS также делает тщательную работу по этому поводу.