Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone and Rails Nested Routes

I have the following routes defined in rails:

resources :accounts do
  resources :transactions
end

This results in urls like:

/accounts/123/transactions/1

Is there an easy way to map this to a backbone model set up?

like image 328
Robert Fall Avatar asked Nov 30 '11 20:11

Robert Fall


4 Answers

Turns out backbone quite easily supports this by nesting a collection in a model as follows:

var Account = Backbone.Model.extend({

  initialize: function() {
    this.transactions = new TransactionsCollection;
    this.transactions.url = '/account/' + this.id + '/transactions';
    this.transactions.bind("reset", this.updateCounts);
  },
});

This achieves exactly what I wanted.

You can read more about it here: http://documentcloud.github.com/backbone/#FAQ-nested

like image 67
Robert Fall Avatar answered Nov 16 '22 08:11

Robert Fall


It might not be an easy way but I think the best way is to use url and set it to a function like this:

var Transaction = Backbone.Model.extend({
    url: function(){
        var url = 'accounts/"+this.account_id+"/transactions';
        if (this.id !== undefined){
            url += "/"+this.id
        }
        return url;
    }
});

Or maybe in coffeescript (as it is backbone+rails):

class Transaction extends Backbone.Model
    url: -> 
        url = "accounts/#{@account_id}/transactions"
        url += "/#{@id}" if @id != undefined
        url

Oh and you could do it more like this(surely with deeper nesting it's better):

var url = ["accounts", this.account_id, "transactions"]
if (this.id !== undefined) url.push(this.id)
return url.join("/")


AFAIK there is now url utility in backbone, and it's not much enough pain for me so that I would search for one in some other library :)

like image 44
PL J Avatar answered Nov 16 '22 07:11

PL J


Backbone does not directly support the creating of nested urls. You must use a function to dynamically calculate the resulting url of your nested object. For example:

var Account = Backbone.Model.extend({

  initialize: function() {
    this.transactions = new TransactionsCollection();
    var self = this;
    this.transactions.url = function () {return self.url + self.id + '/transactions';};
    // etc
  },
});

More information: http://documentcloud.github.com/backbone/#FAQ-nested

like image 2
Alejandro Pablo Tkachuk Avatar answered Nov 16 '22 07:11

Alejandro Pablo Tkachuk


Just define the url of your model or (if you use one) your collection like so:

var MyModel = Backbone.Model.extend({
  url: 'accounts/123/transactions'
});

or dynamically:

mymodel.url = 'accounts/' + accountId + '/transactions';

Those models or all models of a collection that is configured this way will now generate it's backend urls accordingly.

Detailed info:

Model: http://documentcloud.github.com/backbone/#Model-url

Collection: http://documentcloud.github.com/backbone/#Collection-url

like image 1
ProTom Avatar answered Nov 16 '22 09:11

ProTom