ember-model icon indicating copy to clipboard operation
ember-model copied to clipboard

Adding dynamic segment to model's urls

Open gabriel-dehan opened this issue 10 years ago • 1 comments

Hello !

I was looking for a way of having a dynamic part in my model's url. Something like this :

import Ember from "ember";

MyModel = Ember.Model.extend({
  // Relations and stuff
  some_resource: Ember.belongsTo("some-resource", { primaryKey:  'id' }),
});

MyModel.url = "/some_resource/:id/other_resource" // post/:id/comment for instance
MyModel.adapter = Ember.RESTAdapter.create();

export default MyModel;

But that does not work from the get go obviously. I thought of overwriting the buildURL function in my own adapter but we only get the record (before it's fetched, with nothing but a primary key) and I can't manage to get its belongsTo. Is there a built in way to do this or should there be one ?

Thanks !

gabriel-dehan avatar Dec 17 '14 22:12 gabriel-dehan

My take on this issue is the following :

  • Everytime a model is defined with belongsTo and hasMany relationships, before fetching those relations, we iterate through each of the empty relationships models.
  • For each of this models we set a "relationMap" object with a new key corresponding to the parent model id ("parent" in this relationship that is)

For instance if I have a user model with a post belongsTo relation, it will create a relationMap object on the post record :

  somePostRecord.get('relationMap') === {
    user: 2 // Where 2 is the id of the user
  }
  • Now in my post model I would like to do the following :
// Imports and stuffs

MyPostModel = Model.extend({
   // attributes
});

MyPostModel.adapter = Adapter.create();
MyPostModel.url = "user/:user_id/post";

// export and stuff

My Adapter should request user/2/post and get the post.

  • To achieve this I have been rewriting the Ember.RESTAdapter. Mainly the buildURL method, that will now parse the url for a dynamic segment and search in the relationMap the corresponding id. For instance "user/:user_id/post" will look for the "user" key in the relationMap property of the record.

The code can be found here :

You'll notice how it was necessary to define a modelName attribute for the application model. I don't like it much but haven't figured a way out of this definition.

With minor changes, this could actually be implemented directly in the default Ember.RESTAdapter and Ember.Model.

What do you guys think of it ?

gabriel-dehan avatar Dec 19 '14 13:12 gabriel-dehan