mardi 23 juin 2015

How to find a record both by id and query parameters in Ember

I'm trying to use ember-data to send a request via id and query parameters to an endpoint. The end output of the ajax call would be http://ift.tt/1TLVFMD. As far as I know, ember-data's store doesn't have a native way to find by both id and query parameters (neither of the following worked):

// outputs http://ift.tt/1GFrtfs
this.store.find('invoice', 1);

// outputs http://ift.tt/1TLVHnO
this.store.find('invoice, {id: 1, key: value});

Instead, I've been attempting to modify the invoice adapter. Our backend is Django, so we're using the ActiveModelAdapter. I want to override the method that builds the url so that if id is present in the query object, it will automatically remove it and append it to the url instead before turning the rest of the query object into url parameters.

The only problem is that I can't figure out which method to override. I've looked at the docs for ActiveModelAdapter here, and I've tried overriding the findRecord, buildUrl, urlForFind, and urlForQuery methods, but none of them are getting called for some reason (I've tried logging via console.log and Ember.debug). I know the adapter is working correctly because the namespace is working.

Here's my adapter file:

import DS from 'ember-data';
import config from '../config/environment';

export default DS.ActiveModelAdapter.extend({
  namespace: 'v1',
  host: config.apiUrl,

  // taken straight from the build-url-mixin and modified
  // very slightly to test for logging
  urlForFindRecord: function(id, modelName, snapshot) {
    Ember.debug('urlForFindRecord is being called');

    if (this.urlForFind !== urlForFind) {
      Ember.deprecate('BuildURLMixin#urlForFind has been deprecated and renamed to `urlForFindRecord`.');
      return this.urlForFind(id, modelName, snapshot);
    }
    return this._buildURL(modelName, id);
  },

  // taken straight from the build-url-mixin and modified
  // very slightly to test for logging
  findRecord: function(store, type, id, snapshot) {
    Ember.debug('findRecord is being called');

    var find = RestAdapter.prototype.find;
    if (find !== this.find) {
      Ember.deprecate('RestAdapter#find has been deprecated and renamed to `findRecord`.');
      return this.find(store, type, id, snapshot);
    }
    return this.ajax(this.buildURL(type.modelName, id, snapshot, 'findRecord'), 'GET');
  },

  // taken straight from the build-url-mixin and modified
  // very slightly to test for logging
  urlForQuery: function(query, modelName) {
    Ember.debug('urlForQuery is being called');

    if (this.urlForFindQuery !== urlForFindQuery) {
      Ember.deprecate('BuildURLMixin#urlForFindQuery has been deprecated and renamed to `urlForQuery`.');
      return this.urlForFindQuery(query, modelName);
    }
    return this._buildURL(modelName);
  },

  // taken straight from the build-url-mixin and modified
  // very slightly to test for logging
  _buildURL: function(modelName, id) {
    Ember.debug('_buildURL is being called');

    var url = [];
    var host = get(this, 'host');
    var prefix = this.urlPrefix();
    var path;

    if (modelName) {
      path = this.pathForType(modelName);
      if (path) { url.push(path); }
    }

    if (id) { url.push(encodeURIComponent(id)); }
    if (prefix) { url.unshift(prefix); }

    url = url.join('/');
    if (!host && url && url.charAt(0) !== '/') {
      url = '/' + url;
    }

    return url;
  },
});

Is there an easier way to accomplish what I'm trying to do without overriding adapter methods? And if not, what method(s) do I need to override?

Thanks in advance for your help!




Aucun commentaire:

Enregistrer un commentaire