Boffin
Boffin

Reputation: 569

URL of nested Backbone collection

I have Backbone model defined as following:

models.Author = Backbone.Model.extend({
    defaults: {
        id: null,
        name: null,
        books: null     // <-- This is another backbone collection with books of the author
    }    
});

URL which returns collection of author's books is: http://example.com/books?author_id=123

So the question is what's the best way to define URL of Author.books to be as above? Now I set it in Author's class constructor as following:

...
initialize: function(attributes) {
    var bc = new collections.Books();
    bc.url = '/books?author_id' + this.get('id');
    this.set({books: bc});
}
...

I wonder if there better or more right way to do it?

Upvotes: 0

Views: 552

Answers (2)

Nicolas Zozol
Nicolas Zozol

Reputation: 7038

This seems weird for me. I would definitively look for a url like /authors/{authorId}/books to find the Books url of an Author.

So I would create a Backbone.Collection model of Books :

var AuthorCollection = Backbone.Collection.extend({
  model: Book,
  url : function(){
     return this.author.url()+"/books"; // this mean that the AuthorCollection must reference an Author
  }
});

Add it to your Author :

initialize: function() {
    this.books = new AuthorCollection();
    this.books.author = this; // setting the author to the collection
    //this.set({books: bc}); nested models are not recommended in attributes
}

Now calling author24.books.fetch() should shoot the /authors/24/books url.

Take a look at Nested Models FAQ, it's very interesting.

Upvotes: 4

tkone
tkone

Reputation: 22728

Does it work?

Then it's "right".

As far as better goes - that's subjective. There's no "right" or "wrong" way with Backbone for the most part, so if it works, hey, go for it.

The thing you may want to watch out for is that if that author id changes you want to change your URL, so track the change:id message in your initialize

this.on('change:id', function(){
    this.set('books', this.get('books').url = '/books?author_id'+this.get('id');
}, this);

Or something to that extent. Also if you're going to get the author objects back from your server with their book lists attached, you should define a custom parse method that makes the books collection and attaches the book objects to it.

parse: function(resp){
    var books = new collections.Books();
    if(!_.isEmpty(resp.books)){
        _.each(resp.books, function(book){
            var b = new Book();
            b.set(b.parse(book));
            books.add(b, {silent:true});
        });
    }
    resp.books = books;
    return resp;
}

Upvotes: 0

Related Questions