Reputation: 3892
I have an Ember application (with ember data) that is run on a user's machine. There's an API server running on their machine, and one running online. I need to allow users to choose where a model is persisted (the API running on their machine, or the online API). So, two API hosts:
http://localhost:3000
and
http://api.example.com
When a user creates a record, they can set wether they want the record saved locally (through the local API server), or saved online. I persist this choice to a value on the record called dataSource.
So, depending on the record dataSource, I need to set the ember RestAdapter host for the model to the correct value. I understand one can override adapters on a per model basis. For example, I could create a RecordAdapter and manually set the host to a value. However, the host depends on a value in the record, and I'm not sure how to accomplish this with Ember Data, since the rest adapter "host" is a property, not a function.
http://emberjs.com/api/data/classes/DS.RESTAdapter.html#property_host
User flow example:
Upvotes: 0
Views: 1051
Reputation: 6366
You need to override buildURL
on your adapter:
As per Ember Data source, the default implementation for the RESTAdapter is:
/**
Builds a URL for a given type and optional ID.
By default, it pluralizes the type's name (for example, 'post'
becomes 'posts' and 'person' becomes 'people'). To override the
pluralization see [pathForType](#method_pathForType).
If an ID is specified, it adds the ID to the path generated
for the type, separated by a `/`.
@method buildURL
@param {String} type
@param {String} id
@param {DS.Model} record
@return {String} url
*/
buildURL: function(type, id, record) {
var url = [],
host = get(this, 'host'),
prefix = this.urlPrefix();
if (type) { url.push(this.pathForType(type)); }
//We might get passed in an array of ids from findMany
//in which case we don't want to modify the url, as the
//ids will be passed in through a query param
if (id && !Ember.isArray(id)) { url.push(encodeURIComponent(id)); }
if (prefix) { url.unshift(prefix); }
url = url.join('/');
if (!host && url) { url = '/' + url; }
return url;
},
As you can see, buildURL
on your adapter is provided the record so the URL can configured based on that.
The following example shows how you can choose the prefix based on the isLocal
property on your model instances:
// app/adapters/application.js
import Ember from 'ember';
import DS from 'ember-data';
var get = Ember.get;
export default DS.RESTAdapter.extend({
buildURL: function(type, id, record) {
var url = [],
host = get(this, 'host'),
prefix;
// choose prefix based on model setting
if (record && get(record, 'isLocal')) {
prefix = 'http://localhost:3000';
} else {
prefix = this.urlPrefix();
}
if (type) { url.push(this.pathForType(type)); }
//We might get passed in an array of ids from findMany
//in which case we don't want to modify the url, as the
//ids will be passed in through a query param
if (id && !Ember.isArray(id)) { url.push(encodeURIComponent(id)); }
if (prefix) { url.unshift(prefix); }
url = url.join('/');
if (!host && url) { url = '/' + url; }
return url;
},
});
Upvotes: 5