将Ajax与rails update_attributes一起使用

时间:2014-08-27 09:41:14

标签: jquery ruby-on-rails ajax cookies ruby-on-rails-4

使用带有rails方法update_attributes的ajax时遇到问题。在js.coffee文件中,我发送了一个ajax来计算控制器方法。这个ajax很简单,看起来像这样:

            $.ajax({
                url: 'tasks/update_data',
                type: 'POST',
                data: { swap: $.cookie("swap") }
            });

我要做的是刷新页面后保存行交换。这就是我的控制器方法应该做的。当我调试这个方法时,会发生这样的事情:如果我交换一切一切正常;当我交换两次并将值输出到控制台时,其输出类似于第三个< =>秒,第二个< =>首先,但它必须先做第三个< =>秒,第三个< =>。因此我认为db更新的机制有些麻烦,我不明白为什么它会以这种方式工作。在这之间,在所有时候,当调用update_attributes时,它返回true,因此db的更新失败。这就是控制器方法的样子:

def update_data

      ids = params[:swap].split('&')
      puts ids
      puts "--------------------------------------------------"
      row1 = Task.where( id: ids[0] ).first
      row2 = Task.where( id: ids[1] ).first

      puts "first: " + row1.name 
      puts "second: " + row2.name 

      temp_hash1 = { name: row1.name, status: row1.status, project_id: row1.project_id, dead_line: row1.dead_line }
      temp_hash2 = { name: row2.name, status: row2.status, project_id: row2.project_id, dead_line: row2.dead_line }

      k = row1.update_attributes( temp_hash2 )
      puts "first: " + row1.name
      puts k

      m =row2.update_attributes( temp_hash1 )
      puts "second: " + row2.name
      puts m  

      render nothing: true

  end

Cookie值: $.cookie( "swap", $.cookie("swap") + row_id + "&" + prev_row_id, { path: '/' } )。 谢谢你回答。

1 个答案:

答案 0 :(得分:2)

<强> MVC

你的控制器可能会好很多:

#app/controllers/tasks_controller.rb
class TasksController < ApplicationController
   def update_data
      ids = params[:swap].split('&')

      row1 = Task.find ids.first
      row2 = Task.find ids.last

      row1.update row2
      row2.update row1
   end
end

根据经验,永远不要在控制器中包含直接输出(puts)。 Rails为MVC - 意味着所有“输出”都应放入views。虽然你渲染“没有”,但你应该把它转换成你的视图/控制器的某种响应

-

<强>的Ajax

当您调用 ajax 请求时,它就像调用“正常”请求一样。你仍然需要以同样的方式处理它们,即使你不希望得到响应

我的意思是,如果您想接收成功或错误回调,您将需要执行以下操作:

#app/controllers/tasks_controller.rb
class TasksController < ApplicationController
   def update_data
       ...
       @message = "Success"
       respond_to do |format|
          format.js #-> app/views/tasks/update_data.js.erb
       end
   end
end

#app/views/tasks/update_data.js.erb
alert("<%=j @message %>");

-

<强>修正

为了解决您的问题,我建议您退后一步。考虑你想要实现的目标。您提到您正在尝试交换行位置 - 为什么不在position模型中创建Task属性?

这将允许您执行以下操作:

#app/controllers/tasks_controller.rb
class TasksController < ApplicationController
   def update_data
      ids = params[:swap].split('&')

      @row1 = Task.find ids.first
      @row2 = Task.find ids.last

      @row1.update_attributes(position: @row2.position)
      @row2.update_attributes(position: @row1.position)

      #response here
   end
end

我写这篇文章的原因是因为您的应用程序需要object orientated - 这意味着每条记录都需要独立存储到任何其他记录中。

这很重要的原因是因为你正在尝试操纵objects本身 - 在字面意义上“交换”它们。这是荒谬的&amp;效率低下 - 你很多更适合改变各个对象的“位置” - 允许你根据需要改变对象

关于您关于第二次通话的问题 - 您需要更新$.cookie("swap")值才能使其正常工作