Reputation: 854
I have a problem using ajax with rails method update_attributes. In js.coffee file I'm sending an ajax to compute a controller method.This ajax is simple and looks like this:
$.ajax({
url: 'tasks/update_data',
type: 'POST',
data: { swap: $.cookie("swap") }
});
What I'm trying to do is save row swaps after refreshing page. And this is what my controller method supposed to do.When I debug this method, this is what happens: if I swap once everything works fine; when I swap twice and output values to console, its outputs something like this third<=>second, second<=> first,but it must do third<=>second, third<=>first. So I think it's some trouble with mechanics of how db is updating and I don't understand why it works in such way.Between that, in all times, when update_attributes is called, it returns true, so no fail updates of db. This is how controller method looks like:
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 value:
$.cookie( "swap", $.cookie("swap") + row_id + "&" + prev_row_id, { path: '/' } )
.
Thanks for answering.
Upvotes: 0
Views: 901
Reputation: 76774
MVC
Your controller could be a lot better:
#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
As a rule of thumb, never include direct output (puts
) in your controller. Rails is MVC - meaning all the "output" should be placed into your views
. Whilst you render "nothing", you should really translate this into some sort of response for your view / controller
--
Ajax
When you call ajax requests, it's just going to be the same as if you call a "normal" request. You still need to handle them in the same way, even if you don't want to have a response come through
What I mean by this is that if you want to receive success or error callbacks, you'll want to do something like the following:
#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 %>");
--
Fix
In order to fix your issue, I would recommend taking a step back & considering what you're trying to achieve. You mention you're trying to swap row positions - why don't you just create a position
attribute in your Task
model?
This would allow you to do the following:
#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
The reason I write this is because your application needs to be object orientated - meaning that each record needs to be stored independent to any other.
The reason this is important is because you're currently trying to manipulate the objects
themselves - "swapping" them in the literal sense. This is nonsensical & inefficient - you'd be much better suited to just changing the "position" of the respective objects - allowing you to just change the objects as required
In regards to your issue about the second call - you'll need to update your $.cookie("swap")
value in order to make it work correctly
Upvotes: 2