0

I have a model appointment which has many tasks.

Creating a new appointment model which has tasks works fine with backbone. But when i try to update the model with the ids of different tasks it is not working.

I get the following error:

ActiveRecord::AssociationTypeMismatch: Task(#1192000) expected, 
got ActiveSupport::HashWithIndifferentAccess(#2458300)

Parameters:

{"appointment"=>
   {"id"=>"36",
    "customer_id"=>"19",
     "employee_id"=>"10",
     "done"=>"",
     "notes"=>"",
     "starts_at"=>"2012-09-05 13:00:00 +0200",
     "ends_at"=>"2012-09-05 14:30:00 +0200",
     "bookingtype"=>"",
     "tasks"=>
         "[{\"created_at\"=>\"2012-09-04T13:37:17+02:00\",
           \"duration\"=>\"60\", \"id\"=>\"12\",
           \"task_category_id\"=>\"5\", \"updated_at\"=>\"2012-09-04T13:46:13+02:00\"}]",
     "appointment"=>"",
     "task_ids"=>"[\"12\"]"},
     "action"=>"update",
     "controller"=>"appointments",
      "id"=>"36"}

I have some idea that the problem is that there is tasks and task_ids in the request but I have no idea how to fix that in backbone.

My update method looks like this:

    save: function() {
            var self = this;        

            var tasks = [];

            $("input:checked").each(function() {                   
               tasks.push($(this).val());
            });

            this.model.save({starts_at: this.$('#appointment_starts_at_modal').val(), employee_id: this.$('#employeeSelect').val(), customer_id: this.$('#customerSelect').val(),
                        "starts_at(5i)": this.$('#appointment_starts_at_5i_modal').val() , 
                        "ends_at(5i)":  this.$('#appointment_ends_at_5i_modal').val(), task_ids: tasks}, {
            success: function(model, resp) {
                self.model = model;   

                self.close();
            },
            error: function() {
                //new App.Views.Error();
            }
        });
        return false;
    },
Ben
  • 2,560
  • 4
  • 29
  • 43

1 Answers1

1

From the error, it sounds like a ruby issue and I'm not familiar with ruby at all. But, with respect to Backbone, it shouldn't be a problem that you have a "tasks" and "task_ids" attribute in your appointment model. Backbone will happily send those over to your server as JSON data. Note however, that when working with nested collections in Backbone, the way you're passing the ids as an attribute outside of the task models is a bit odd. :-)

I can talk a little bit about what I see from a Backbone perspective though.

I'm assuming your tasks_ids attribute represents an array of ids of all the tasks you have. tasks is an array() of task JSON objects. In Backbone, when working with nested collections and such, usually the id attribute of each task would be part of the task object. So if I made an app that sent a bunch of tasks data as an array, it would send looking like this:

"tasks"=>
     "[{\"id"=>\"12\", \"created_at\"=>\"2012-09-04T13:37:17+02:00\",
       \"duration\"=>\"60\", \"id\"=>\"12\",
       \"task_category_id\"=>\"5\", \"updated_at\"=>\"2012-09-04T13:46:13+02:00\"}]",

When I work with nested collections I basically make sure the ids and all attributes of some model are encapsulated by the object.

// My fake JSON
{'id':'1', 'appointment':{
    'id':'50',
    'tasks':[
        {'id':'100', 'taskName':'groceries' /* etc. */},
        {'id':'200', 'taskName':'bank errand'}
    ]
}}

When my appointment model receives this fetched data, I'll either process it in my parse() or modified set() method. I'll just demonstrate what I do with parse()

// Inside my appointment model definition
parse: function(response) {
    if (_.isUndefined(this.tasks)) {
        this.tasks = new TasksCollection();
    }
    this.tasks.reset(response.tasks);
    delete response.tasks;

    return response;
}

Something like the above. My TasksCollection would have model: Task defined so resetting with an attributes hash will populate my collection nested inside my appointment model with the appropriate data (with ids included.)

I don't think this solves your problem, but since you were alluding to the Backbone way of doing things I thought having this way (among many) illustrated might give you some ideas.

jmk2142
  • 8,581
  • 3
  • 31
  • 47