这是我第一次使用Rails' AJAX助手。我有AJAX删除工作正常与远程true,但我现在遇到的问题是check_box_tag。在其他一些SO Q& A的帮助下,我尝试设置一个非常基本的待办事项列表,其中每个任务都有一个复选框。当用户点击该复选框时,它应该通过一个名为“已完成”的方法发送一个AJAX PUT请求。并使用true或false更新该任务的相应数据库列,然后不进行任何操作。
所以我遇到了两个问题:
目前数据库尚未更新,在Chrome控制台中,当我点击复选框时,它显示404错误。
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'
我使用嵌套资源,因为项目通过ProjectTasks等有很多任务,所以我想知道问题是否在这个领域的某个地方。我的自定义路由与其他路由的格式相同,因此我很困惑为什么它未定义且ajax回调没有处理。
routes.rb中:
resources :projects do
resources :tasks
end
put 'projects/:project_id/tasks/:id/completed' => 'tasks#completed'
佣金路线:
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:
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:
<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:
$ ->
$('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')
非常感谢任何正确方向的帮助。
答案 0 :(得分:0)
我能够弄清楚这一点。但是,这可能不是最干净的Rails方式。我需要将项目ID传递给url,这在早期很明显,并且还使用data-url属性将此信息传递给javascript。
_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) %>
然后将其分配给变量并返回带有.js的URL。这导致修复404问题。
tasks.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
要通过已完成的方法更新数据库列,我需要引用相应的列。
tasks_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
现在,当用户选中或取消选中复选框时,任务在数据库中被标记为已完成(真或假),而不会刷新页面。