10

We recently made the switch from Ember to Ember CLI and I'm not able to find the proper convention for associating a model with a custom adapter.

History We created an adapter for models that have a file upload as part of their Create route so that form data and binary data could be pushed to one endpoint in our backend api [rails]. The adapter uses the FormData object for adding the file to the request. I opted to only use this adapter for models with files and have non-file upload models use the application adapter. So I would like the ember app to support multiple adapters.

Custom Adapter: in adapters/file-upload.js

import DS from 'ember-data';

var FileUploadAdapter = DS.ActiveModelAdapter.extend({
    ajaxOptions: function(url, type, hash) {
        var self = this;
        hash = hash || {};
        hash.url = url;
        hash.type = type;
        hash.dataType = 'json';
        hash.context = this;

        //add post data to formdata object
        if (hash.data && type != 'GET' && type !='DELETE') {
          hash.processData = false;
          hash.contentType = false;
          var fd = new FormData();
          var root = Object.keys(hash.data)[0];

          for (var i = 0; i < Object.keys(hash.data[root]).length; i++) {
            var key = Object.keys(hash.data[root])[i];
            if (hash.data[root][key]) {
              fd.append(root + "[" + key + "]", hash.data[root][key]);
            }
          }
          hash.data = fd;
        }

        var headers = this.get('headers');
        if (headers) {
          hash.beforeSend = function(xhr){
            for (var i = 0; i < Ember.keys(headers).length; i++) {
              xhr.setRequestHeader(Ember.keys(headers)[i], headers[Ember.keys(headers)[i]]);
            }
          }
        }

        return hash;
    }
});

export default FileUploadAdapter;

In "classic" Ember, I was able to tell ember to use a specific adapter on a model through this convention:

//given a model name "Person", specific adapter via {ModelName}Adapter
App.PersonAdapter = App.FileUploadAdapter.extend();

But now that we don't have these global objects in Ember CLI, is there a way to specify an adapter? I assume that I will want to assign my model to a variable before exporting it and doing additional settings work there.

I desire to fit within the ember cli paradigm, so please let me know if you think this is moving too far away from it. I could go back to using one adapter and doing file detection within it, but separating custom functionality into multiple adapters feels cleaner.

Thanks!

Dhaulagiri
  • 3,281
  • 24
  • 26
William Newby
  • 621
  • 5
  • 14

1 Answers1

21

Ember Data uses the resolver to look up adapters. A per-type adapter is looked up via adapter:<type>, so for a Person, this is adapter:person.

ember-cli uses es6 modules and the jj-abrams-resolver to look up these modules based on file names. Usually the lookup is like this: <type>:blah would look for <type>s/blah, so for an adapter:person it will look for adapters/person.

To wire up a PersonAdapter that extends your FileUploadAdapter (located in adapters/file-upload) you can do this:

// adapters/person.js

import FileUploadAdapter from './file-upload';

export default FileUploadAdapter.extend();

You can check the resolver in the console of your app:

// where `App` is the Global name for your app.
var applicationAdapter = App.__container__.lookup('adapter:application');
var personAdapter = App.__container__.lookup('adapter:person');
tstirrat
  • 1,056
  • 9
  • 9