Search code examples
ember.jsember-dataember-routerember-model

Ember Data mix of find(), query(), findAll()


If I do

this.get('store').findAll('model')

It will make a request to /models and it will expect for an array. On the other hand, if I do

this.get('store').find('model', my_id)

It will make a request to /models/my_id and it will expect for one record of my model. The method .query() will basically do a GET request with the parameters I pass like

this.get('store').query('model', {something: 'foo'})

It will make a request to /models?something=foo.

My question is the following:

Can I make something which mixes all the three methods above? I want to make a request to the path /models/foo and I want to expect one array.

I did .find('model', params.something), but it threw an assert exception saying that it was expecting for one model and not one array.


Solution

  • I'm assuming you're using the RestAdapter and you only want to do this for one model. In which case you can just customise your adapter by modifying the methods of the BuildURLMixin class. So if you wanted to specify the /models/foo as the url for query then you could implement urlForQuery in your custom adapter like:

    urlForQuery(query, modelName) {
      return '/models/foo';
    },
    

    EDIT: If you want complete control over your url you can customise buildUrl

    buildURL(modelName, id, snapshot, requestType, query) {
      switch (requestType) {
        case 'query':
          return '/models/' + query.something;
        default:
          return this._super();
      }
    },
    

    Then you when you call:

     this.get('store').find('model', {something: 'foo'})
    

    it will hit /models/foo with no querystring.

    EDIT2: Turns out the querystring gets appended way later than I thought. In fact to do what you want you're going to have to customise the query method of your adapter. If you look at the source for the RestAdapter you can see it adds the query at the point it calls the url:

    return this.ajax(url, 'GET', { data: query });
    

    So you can customise it to just:

    return this.ajax(url, 'GET', { });
    

    but you should be aware of the knock on effects i.e. no querystrings being applied at all