David Tuite
David Tuite

Reputation: 22643

Prevent saving if child model is invalid?

I have a bus model, which has a nested route model.

class Busables.Models.Bus extends Backbone.Model
  url: '/buses'
  defaults:
    route: new Busables.Models.Route()

Then I have an overall error view which listens to the error events of the bus model and it's route.

class Busables.Views.Errors extends Backbone.View
  el: '#error-area'
  template: JST['shared/error']

  # model in this instance is a bus
  initialize: ->
    @model.get('route').bind 'error', this.routeError, this
    @model.bind 'error', this.busError, this

So, when the user submits a form on the page, I save an attribute of the bus, and send it to the server:

class Busables.Views.NewBus extends Backbone.View
  ...

  saveBus: (event) ->
    event.preventDefault()

    @model.save {
      seats: this.$('#bus_seats').val(),
    }, {
      success: (model, response) ->
        console.log "Success. The model and response: ", model, response
        window.location.href = "/buses/#{response.id}"
    }

So the question is, how do I trigger validation of the nested route while I'm saving the bus?

Upvotes: 1

Views: 412

Answers (1)

Derick Bailey
Derick Bailey

Reputation: 72868

You'll need to override the validate method on your Bus and have it call the validation for the nested route.

The validate method is called any time your model is updated or being saved, giving you an opportunity to prevent invalid data from making it's way in to your model or back to the server. If you return any value from validate method that is not falsy, then the validate method will prevent the save or attribute update.

Bus = Backbone.Model.extend({
  validate: function(attrs){
    var invalidBus = false; // do your real bus validation here

    var route = this.get("route");
    var invalidRoute = route.validate(route.toJSON());

    return invalidBus || invalidRoute;
  }
});

Route = Backbone.Model.extend({
  validate: function(attrs){
    // do your route validation here
    // return an 'invalid' status
  }
});

I would also recommend looking at the Backbone-Relational plugin. It handles a lot of this for you, and chances are you'll be re-writing code that is already available in that plugin, if you do this yourself.

Upvotes: 1

Related Questions