I just answered you on Stack Overflow, but I figured I'd post my answer here too. I'm also curious what other folks in the CanJS community think about this idea, because I had been searching for a solution myself.
My own solution was inspired by trickey's suggestion in this post about modifying the "serialize" model method to make it play more nicely with Rails. The way this works is that I add a "include" field on my models where you can list the attributes you'd like to include (patterned after the Rails as_json method).
- can.Model("BaseModel", {}, {
- serialize: function() {
- var data, retval, serialized;
- data = {};
- retval = {};
- serialized = can.Model.prototype.serialize.call(this);
- if (typeof this.constructor.include !== 'undefined') {
- can.each(this.constructor.include, function(attr) {
- data[attr] = serialized[attr];
- });
- } else {
- data = serialized;
- }
- //wrap the return value in the model name for Rails purposes, e.g. {"event": {data}}
- retval[this.constructor._shortName] = data;
- return retval;
- }
- });
Then in my model I use the "include" array to indicate which fields I want to include. By omitting "attendees" and "speakers", those associated models will not be packaged into my serialized JSON that gets sent back to the server.
- Event = BaseModel.extend('Event', {
- findAll: "GET /admin/events",
- findOne: "GET /admin/events/{id}",
- create: "POST /admin/events",
- update: "PUT /admin/events/{id}",
- destroy: "DELETE /admin/events/{id}",
- attributes: {
- attendees: 'Models.User.models',
- speakers: 'Models.User.models'
- },
- include: ['id', 'name', 'start_time', 'end_time']
- }, {});