fetchRelated not fetching related
Asked Answered
I

2

5

Been trying to get this up and running for a while now. Basically i have a rest api as backend that returns json, all fine.

The problem i have is with backbone-relational. I'm sure i've just got something wrong but i've been searching the nets for a while and couldn't find anything to help.

I'm trying to get a has many relationship between the model "Profession" and "Weapon". Here's my code for that:

Profession = Backbone.RelationalModel.extend({
    urlRoot: '../api/professions',

    relations: [{
        type: Backbone.HasMany,
        key: 'weapons',
        relatedModel: 'Weapon',
        collectionType: 'Weapons',
        reverseRelation: {
            key: 'profession',
            includeInJSON: 'id',
            keySource: 'profession_id'
        }
    }]
});

Weapon = Backbone.RelationalModel.extend({
    urlRoot: '../api/weapons'
});
Weapons = Backbone.Collection.extend({
    model: Weapon,

    url: function(models){
        return '../api/weapons';
    }
});

And a call to those api endpoints returns:

{name: "Profession1", id: 1}

[{name: "Weapon1", profession_id: 1}, {name: "Weapon2", profession_id: 1}]

So, if i understand correctly a profession.fetchRelated('weapons') should send an httprequest to the url for the weapons collection and pull the object which have a profession_id of 1. But nothing happens when i run profession.fetchRelated('weapons')

Instead answered 15/3, 2012 at 6:56 Comment(0)
B
9

So, if i understand correctly a profession.fetchRelated('weapons') should send an httprequest to the url for the weapons collection and pull the object which have a profession_id of 1. But nothing happens when i run profession.fetchRelated('weapons')

This is not how I understand Backbone-relational to work - with the caveat that I'm working with an older version, and have not yet investigated the latest versions.

From my understanding, Backbone-relational wants data that looks different from your API responses.

I think that Backbone-relational wants references to nested models in the parent model response, either fully nested:

{
  name: "Profession1", 
  id: 1, 
  weapons: [
    {name: "Weapon1", profession_id: 1}, 
    {name: "Weapon2", profession_id: 1}
  ]
}

In which case, it will fully populate the nested models.

Or, as references:

{
  name: "Profession1", 
  id: 1, 
  weapons: ['weapon1','weapon2']
}

In which case Backbone-relational will stash the related keys internally, but present an empty collection. You would then use fetchRelated to fetch the full data for the related models:

assassin.fetchRelated('weapons')

Which make a request for weapons with id 'weapon1' and 'weapon2', either as individual requests, or if your API accepts a set request, a single request, expecting a response something like:

{id: 'weapon1', name: "Weapon1", profession_id: 1}

I don't, off the top of my head, know if there's a quick, built-in way to work with your API responses, other then to write a custom function.

Bursa answered 15/3, 2012 at 14:34 Comment(2)
Thanks for the clarification. Maybe i should just change the API response to include the nested models as i want them to be available as soon as the "profession" is fetched.Instead
The problem I encounter is when you have dozens of professions, each with dozens of slightly overlapping weapons. Including the full weapon object with each profession leads to heaps of redundant data. It's great for this small example, but for a large application, not quite as feasible.Benzvi
G
2

To add to what Edward wrote, here's how you can get fetchRelated to work. First, as Edward claimed, fetchRelated will return nothing if your API already nests the data in the JSON response. So, if in Django-Tastypie you have your resource set up to use full=True:

movies = fields.ToManyField('movie.api.MovieResource', 'user', full=True)

then something like,

myuser.fetchRelated("movies")

will return nothing because the related data will already be included in the JSON response. But where fetch related is particularly useful is when you are attempting to do some lazy loading. So, if you have full=False in your Django-Tastypie field, and your JSON response only includes the id's and resource URI to that entry, you can use fetchRelated to actually populate that data.

myuser = new User({id: 1})
myuser.fetch()
myuser.fetchRelated("movies")

And now you have access to the related movies collection. If you're also using the Tastypie-Backbone plugin, you don't need to worry about constructing a special URL return statement in the Collection. It does it all for you using the tastypie select syntax of /2;3;7

Gradus answered 23/5, 2012 at 22:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.