Backbone wants to include created_at, updated_at,

2019-02-27 04:29发布

问题:

I'm using Backbone with Rails. I have a model that I can create and destroy just fine. When I edit, though, I get this error:

Can't mass-assign protected attributes: created_at, id, updated_at

That makes sense. Those attributes are protected and they should be protected. Backbone shouldn't be trying to update these attributes, but Backbone doesn't know better.

One option, of course, would be to remove params[:created_at], etc. in my Rails controller, but I can imagine that getting really un-DRY pretty quick, and plus it just seems wrong to have to do that.

Is there a way for me to tell Backbone not to include these attributes in its forms?

回答1:

Either don't send them to the client so that your Backbone model never knows about them or override toJSON in your model to exclude them.

The default toJSON implementation is very simple:

toJSON: function() {
    return _.clone(this.attributes);
}

so you can replace it with this:

toJSON: function() {
    var attrs = _(this.attributes).clone();
    delete attrs.created_at;
    delete attrs.updated_at;
    return attrs;
}

You could even monkey patch that right into Backbone.Model.prototype if that made sense to you.

The downside of altering toJSON is that toJSON tends to do double duty in Backbone:

  1. toJSON is used to serialize models and collections for the server.
  2. toJSON is used to serialize models and collections for views.

If you still want to use updated_at and created_at in views then I'd recommend adding another method, say serialize_for_view, that does what the standard toJSON does:

serialize_for_view: function() {
    return _(this.attributes).clone();
}

and then use things like var html = this.template({m: this.model.serialize_for_view()}) to build your view's HTML. You could also monkey patch serialize_for_view into Backbone.Model.prototype if you wanted to use it everywhere.



回答2:

I found that putting

model.unset("created_at");
model.unset("updated_at");
model.save() 

fixed the problem. This won't work if you need those attributes, but if they are not needed, this works.