How to respond to ajax call in Rails

7.5k views Asked by At

I know there are many questions about that already on stackoverflow but none of them has been useful for me. Here is my ajax code:

function update_schedule($task){
  var taskId = $task.data("taskId"),
    startHour, endHour,
    userId = $('#users').val();
  if( !$task.hasClass('daily-task')){ 
    startHour = getStartHour($task),
    endHour = startHour + (+$task.data('time'));
  }
  console.log(startHour, endHour)

   $.ajax({
          url: '/heimdall/update_scheduled_task',
          method: 'POST',
          data: { "task_id": taskId, "start_hour": startHour, "end_hour": endHour, "user_id": userId },
          success: function (){
            console.log("SUCESS!!", data['head'])
          },
          error: function () {
              console.log("FAILURE");
          },
          async: true
    }); 
}

The controller code:

def update_scheduled_task
    scheduled_task = ScheduledTask.find_or_create_by(task_id: params[:task_id])
    scheduled_task.update_attributes(start_hour: params[:start_hour], end_hour: params[:end_hour], task_id: params[:task_id], user_id: params[:user_id])

  end

I want to return the id of found or created task. I don't know how to send/receive this information. I've read about respond to but still I don't know how to use it in this case.

3

There are 3 answers

3
Abhi On BEST ANSWER

You may do render json: ... to return the required info to ajax in JSON format:

def update_scheduled_task
  scheduled_task = ScheduledTask.find_or_create_by(task_id: params[:task_id])
  scheduled_task.update_attributes(start_hour: params[:start_hour], end_hour: params[:end_hour], task_id: params[:task_id], user_id: params[:user_id])

  render json: {scheduled_task_id: scheduled_task.id}
end

And in the ajax function's success, use it like:

success: function (data){
  var data = JSON.parse(data);

  console.log(data["scheduled_task_id"]);
},
0
Leonel Galán On

jQuery's success and error callbacks rely on the status code returned by the controller. Make sure that you return the right status code when you are unable to create/read/update the object. On success, simply render a JSON with the id property set. I beleive update_attributes returns true on success:

if scheduled_task && scheduled_task.update_attributes(...)
  render json: { id: scheduled_task.id }
else
  head :unprocessable_entity
end
0
Camilo Camargo On

First, you need to improve your controller code structure (You can rely on the default scaffold generator methods). Then, you must indicate that your method will respond to json format only, with the answer you want to return, something like this:

def update_scheduled_task
  scheduled_task = ScheduledTask.find_or_create_by(task_id: params[:task_id])
  if (scheduled_task && scheduled_task.update_attributes(start_hour: params[:start_hour], end_hour: params[:end_hour], task_id: params[:task_id], user_id: params[:user_id]))
    render json: { scheduled_task_id: scheduled_task.id }
  else
    render json: { error: l18n.t("error.messages.request_error") }
  end
end

Then, you must modify the success and failure response methods of the jquery ajax request. Here's an example of how it might look:

$.ajax({
  url: "/heimdall/update_scheduled_task",
  method: "post",
  data: { task_id: taskId, start_hour: startHour, end_hour: endHour, user_id: userId },
  success: function(result) {
    if (result["scheduled_task_id"] != null) {
      console.log("Schedule record => " + result["scheduled_task_id"])
    } else {
      console.log("Error: " + result["error"])
    }
  },
  error: function() {
    console.log("Ajax request error");
  },
  // async: true => By default JQuery set true to async param.
});

Do not forget that you need to add a rule to access this method in the file config/ruotes.rb, something like this:

post update_scheduled_task, :defaults => { :format => 'json' }

I hope this helped you, regards!