-
Notifications
You must be signed in to change notification settings - Fork 49
/
drf.js
135 lines (125 loc) · 4.19 KB
/
drf.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import DS from 'ember-data';
import Ember from 'ember';
/**
* The Django REST Framework adapter allows your store to communicate
* with Django REST Framework-built APIs by adjusting the JSON and URL
* structure implemented by Ember Data to match that of DRF.
*
* The source code for the RESTAdapter superclass can be found at:
* https://github.com/emberjs/data/blob/master/packages/ember-data/lib/adapters/rest_adapter.js
*
* @class DRFAdapter
* @constructor
* @extends DS.RESTAdapter
*/
export default DS.RESTAdapter.extend({
defaultSerializer: "DS/djangoREST",
addTrailingSlashes: true,
/**
* Determine the pathname for a given type.
*
* @method pathForType
* @param {String} type
* @return {String} path
*/
pathForType: function(type) {
var dasherized = Ember.String.dasherize(type);
return Ember.String.pluralize(dasherized);
},
/**
* Build 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').
*
* If an ID is specified, it adds the ID to the path generated for
* the type, separated by a `/`.
*
* If the adapter has the property `addTrailingSlashes` set to
* true, a trailing slash will be appended to the result.
*
* @method buildURL
* @param {String} type
* @param {String} id
* @param {DS.Snapshot} snapshot
* @return {String} url
*/
buildURL: function(type, id, snapshot, requestType) {
var url = this._super(type, id, snapshot, requestType);
if (this.get('addTrailingSlashes')) {
if (url.charAt(url.length - 1) !== '/') {
url += '/';
}
}
return url;
},
/**
* Takes an ajax response, and returns an error payload.
*
* Returning a `DS.InvalidError` from this method will cause the
* record to transition into the `invalid` state and make the
* `errors` object available on the record.
*
* This function should return the entire payload as received from the
* server. Error object extraction and normalization of model errors
* should be performed by `extractErrors` on the serializer.
*
* @method ajaxError
* @param {Object} jqXHR
* @return {DS.InvalidError} or {Object} jqXHR
*/
ajaxError: function(jqXHR) {
var error = this._super(jqXHR);
if (jqXHR && jqXHR.status === 400) {
var jsonErrors;
try {
jsonErrors = Ember.$.parseJSON(jqXHR.responseText);
} catch (SyntaxError) {
// This happens with some errors (e.g. 500).
return error;
}
// The field errors need to be in an `errors` hash to ensure
// `extractErrors` / `normalizeErrors` functions get called
// on the serializer.
var convertedJsonErrors = {};
convertedJsonErrors['errors'] = jsonErrors;
return new DS.InvalidError(convertedJsonErrors);
} else {
return error;
}
},
/**
* Fetch several records together if `coalesceFindRequests` is true.
*
* @method findMany
* @param {DS.Store} store
* @param {subclass of DS.Model} type
* @param {Array} ids
* @param {Array} snapshots
* @return {Promise} promise
*/
findMany: function(store, type, ids, snapshots) {
Ember.Logger.warn('WARNING: You are fetching several records in a single request because ' +
'you have set `coalesceFindRequests=true` on the adapter. For this to ' +
'work, you MUST implement a custom filter in Django REST Framework. See ' +
'http://dustinfarris.com/ember-django-adapter/coalesce-find-requests/ ' +
'for more information.');
return this._super(store, type, ids, snapshots);
},
/**
* This is used by RESTAdapter.groupRecordsForFindMany.
*
* The original implementation does not handle trailing slashes well.
* Additionally, it is a complex stripping of the id from the URL,
* which can be dramatically simplified by just returning the base
* URL for the type.
*
* @method _stripIDFromURL
* @param {DS.Store} store
* @param {DS.Snapshot} snapshot
* @return {String} url
*/
_stripIDFromURL: function(store, snapshot) {
return this.buildURL(snapshot.modelName);
}
});