简体   繁体   English

带有check_box_tag的Rails AJAX在单击时抛出404错误

[英]Rails AJAX With check_box_tag Throwing 404 Error On Click

This is my first time working with Rails' AJAX helpers. 这是我第一次与Rails的AJAX帮助程序一起工作。 I got AJAX delete to work fine with remote true but the problem I'm having now is with check_box_tag. 我将AJAX删除与远程true配合使用可以正常工作,但是我现在遇到的问题是check_box_tag。 With the help of a few other SO Q&A's I'm trying to setup a pretty basic ToDo List where each task has a checkbox. 在其他一些SO Q&A的帮助下,我试图设置一个非常基本的待办事项列表,其中每个任务都有一个复选框。 When a user clicks the checkbox it is supposed to send an AJAX PUT request through a method called 'completed' and updates the corresponding database column for that task, with true or false, then render nothing. 当用户单击复选框时,它应该通过一种称为“ completed”的方法发送AJAX PUT请求,并使用true或false更新该任务的相应数据库列,然后不呈现任何内容。

So there are two issues I'm running into: 因此,我遇到了两个问题:
Right now the database isn't updating and in Chrome console it's showing a 404 error when I click a checkbox. 现在,数据库未更新,并且在Chrome控制台中,当我单击复选框时,它显示404错误。

Stacktrace is showing 'Couldn't find Project with id=undefined': Stacktrace显示“无法找到id = undefined的项目”:

Started PUT "/projects/undefined/tasks/61/completed/" for 127.0.0.1 at 2013-06-10 16:55:55 -0500
Processing by TasksController#completed as HTML
Parameters: {"id"=>"61", "completed"=>"true", "project_id"=>"undefined"}
Project Load (0.2ms)  SELECT "projects".* FROM "projects" WHERE "projects"."id" = ? LIMIT 1  [["id", "undefined"]]
Completed 404 Not Found in 3ms

ActiveRecord::RecordNotFound (Couldn't find Project with id=undefined):
app/controllers/tasks_controller.rb:68:in `completed'

I'm using nested resources since Projects have many Tasks through ProjectTasks, etc., so I'm wondering if the issue is somewhere in this area. 我正在使用嵌套资源,因为Projects通过ProjectTasks等具有许多任务,因此我想知道问题是否在该领域。 My custom route matches the same format as the other routes so I'm confused why it's undefined and the ajax callback isn't processing. 我的自定义路由与其他路由的格式相同,因此我很困惑为什么未定义路由,而ajax回调未处理。

routes.rb: route.rb:

resources :projects do
  resources :tasks
end

put 'projects/:project_id/tasks/:id/completed' => 'tasks#completed'

rake routes: 耙路:

root        /                                                   projects#index
project_tasks GET    /projects/:project_id/tasks(.:format)               tasks#index
              POST   /projects/:project_id/tasks(.:format)               tasks#create
new_project_task GET    /projects/:project_id/tasks/new(.:format)           tasks#new
edit_project_task GET    /projects/:project_id/tasks/:id/edit(.:format)      tasks#edit
project_task GET    /projects/:project_id/tasks/:id(.:format)           tasks#show
              PUT    /projects/:project_id/tasks/:id(.:format)           tasks#update
              DELETE /projects/:project_id/tasks/:id(.:format)           tasks#destroy
projects GET    /projects(.:format)                                 projects#index
              POST   /projects(.:format)                                 projects#create
new_project GET    /projects/new(.:format)                             projects#new
edit_project GET    /projects/:id/edit(.:format)                        projects#edit
      project GET    /projects/:id(.:format)                             projects#show
              PUT    /projects/:id(.:format)                             projects#update
              DELETE /projects/:id(.:format)                             projects#destroy
              PUT    /projects/:project_id/tasks/:id/completed(.:format) tasks#completed

tasks_controller.rb: task_controller.rb:

def completed
  @project = Project.find(params[:project_id])
  @task = @project.tasks.find(params[:id])

  respond_to do |format|
    if @task.update_attributes(params[:task])
      format.html { redirect_to(project_tasks_path(@project.id)) }
      format.js   { render :nothing => true }
    end
  end
end

_task.html.erb: _task.html.erb:

<ul>
  <% @tasks.each do |task| %>
    <li>
      <%= check_box_tag task.id, task.completed ? 'false' : 'true', task.completed, :url => url_for(:action => 'completed', :id => task.id) %>
      <%= task.name %>
      <%= link_to 'Edit', edit_project_task_path(@project.id, task.id) %> |
      <%= link_to 'Delete', project_task_path(@project.id, task.id), confirm: "Are you sure you want to delete this task?", method: :delete, remote: true, class: 'delete_task' %>
    </li>
  <% end %>
</ul>

tasks.js.coffee: task.js.coffee:

$ ->
  $('input:checkbox').change ->
    checked = undefined
    if $(this).is(":checked")
      checked = true
    else
      checked = false
    $.ajax
      type: "PUT"
      url: "/projects/" + $(this).attr('project_id') + "/tasks/" + $(this).attr('id') + "/completed/"
      dataType: "html"
      data:
        id: $(this).attr('id')
        completed: checked
      success: (data, textStatus, jqXHR) ->
        alert("Task has been marked as completed!")

$ ->
  $('input:checkbox').change ->
    if ( $(this).is(':checked') )
      $(this).parent().addClass('marked')
    else
      $(this).parent().removeClass('marked')

Any help in the right direction would be much appreciated. 在正确方向上的任何帮助将不胜感激。

I was able to figure this out. 我能够弄清楚这一点。 This might not be the cleanest Rails way, however. 但是,这可能不是最干净的Rails方式。 I needed to pass in the project id to the url, which was obvious early on and also used the data-url attribute to pass this information through to javascript. 我需要将项目ID传递给url,这在早期很明显,并且还使用data-url属性将该信息传递给javascript。

_tasks.html.erb _tasks.html.erb

<%= check_box_tag task.id, task.completed ? 'false' : 'true', task.completed, 'data-url' => url_for(:action => 'completed', :project_id => @project.id, :id => task.id) %>

Then assign it to a variable and return the url with .js. 然后将其分配给变量,并使用.js返回url。 This resulted in fixing the 404 issue. 这样就解决了404问题。

tasks.js.coffee task.js.coffee

$ ->
  $('input:checkbox').change ->
    checked = undefined
    url = $(this).data("url")
    if $(this).is(":checked")
      checked = true
    else
      checked = false
    $.ajax
      type: "PUT"
      url: url + ".js"
      data:
        id: $(this).attr('id')
        completed: checked

For updating the database column via the completed method, I needed to reference the corresponding column. 为了通过完成的方法更新数据库列,我需要引用相应的列。

tasks_controller.rb task_controller.rb

def completed
  @project = Project.find(params[:project_id])
  @task = @project.tasks.find(params[:id])

  respond_to do |format|
    if @task.update_attributes(:completed => params[:completed])
      format.html { redirect_to(@task) }
      format.js   { render :nothing => true }
    end
  end
end

Now the task is marked as completed (true or false) in the database when a user checks or unchecks a checkbox, without the page refreshing. 现在,当用户选中或取消选中复选框而不刷新页面时,该任务在数据库中被标记为已完成(是或否)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM