From 87d5dab8df3b4bf3417654ded68a670315fedd3e Mon Sep 17 00:00:00 2001 From: Ryan M Harrison Date: Thu, 27 Oct 2016 03:16:14 -0400 Subject: [PATCH] Update README to include example scenarios, #25 There is no silver bullet when it comes to passing application data to `urlSegment` The README should reflect this fact. --- README.md | 159 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 158 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a0ddaa4..d778d06 100644 --- a/README.md +++ b/README.md @@ -28,8 +28,140 @@ ember-data-url-templates `>= 0.1.0` is known to work with ember-data `>= 1.0.0-b More in depth documentation can be found in [the wiki](https://github.com/amiel/ember-data-url-templates/wiki). -### Synopsis +### Examples +`urlSegments` are used to build dynamic portions of the url. +The appropriate mechanism for passing data from the application to `urlSegments` depends on i) the `DS.store` method used, and ii) where the passed state-data is stored. +#### snapshot +```javascript +// adapters/comment + +import Ember from "ember"; +import DS from "ember-data"; +import UrlTemplates from "ember-data-url-templates"; + +export default DS.RESTAdapter.extend(UrlTemplates, { + urlTemplate: '{+host}/comments{/id}', + urlForCreateRecord: '{+host}/users/{userId}/comments', + + urlSegments: { + userId(type, id, snapshot, query) { + return snapshot.belongsTo('user').id;; + } + } +}); +``` + +```javascript +var user = this.store.peekRecord('user', 1); +store.createRecord('comment', { + title: "Tomster and Zoey", + user: user +}); +``` + +Usage conditions: +- [Adapter](http://emberjs.com/api/data/classes/DS.JSONAPIAdapter.html) must have argument `snapshot` +- Relationship must already be defined in snapshot, e.g. `belongsTo()`, `hasMany()` + +Most appropriate for: +- `DS.store.createRecord()` +- `DS.store.deleteRecord()` + +#### snapshot with `adapterOptions` +```javascript +// adapters/comment + +import Ember from "ember"; +import DS from "ember-data"; +import UrlTemplates from "ember-data-url-templates"; + +export default DS.RESTAdapter.extend(UrlTemplates, { + urlTemplate: '{+host}/comments{/id}', + urlForFindAll: '{+host}/users/{userId}/comments', + + urlSegments: { + userId(type, id, snapshot, query) { + return snapshot.adapterOptions.userId; + } + } +}); +``` + +```javascript +// routes/users/user/comment +import Ember from 'ember'; + +export default Ember.Route.extend({ + model: function(params) { + let user = this.modelFor("users.user"); + return this.store.findAll('comment', {adapterOptions: {userId: user.id}}); + } +}); +``` + +Usage conditions: +- [`DS.store`](http://emberjs.com/api/data/classes/DS.Store.html) must have arguement `options` +- [Adapter](http://emberjs.com/api/data/classes/DS.JSONAPIAdapter.html) must have argument `snapshot` + +Most appropriate for: +- `DS.store.findRecord()` +- `DS.store.findAll()` + +Gotchas: +- Snapshots are the canonical way of safely handling a record before making an API request via EmberData, but... +- Requires explictly passing `adapterOptions` with *all* `find` and `findRecord`calls. + * NB: The above is a minimal working example. In production, you'd want to ensure that required `adapterOptions` have been passed to `userId()` via the `snapshot`. + +#### query +```javascript +// adapters/comment + +import Ember from "ember"; +import DS from "ember-data"; +import UrlTemplates from "ember-data-url-templates"; + +export default DS.RESTAdapter.extend(UrlTemplates, { + urlTemplate: '{+host}/comments{/id}', + queryUrlTemplate: '{+host}/users/{userId}/comments{?query*}', + + urlSegments: { + userId(type, id, snapshot, query) { + let userId = query.userId; + delete query.userId // Work-around. Otherwise, the query string will include `userId` + return userId; + } + } +}); +``` + +```javascript +// routes/users/user/comment +import Ember from 'ember'; + +export default Ember.Route.extend({ + model: function(params) { + let user = this.modelFor("users.user"); + return this.store.queryRecord('comment', { userId: user.id }); + } +}); +``` + +Usage conditions: +- [`DS.store`](http://emberjs.com/api/data/classes/DS.Store.html) must have arguement `query` +- [Adapter](http://emberjs.com/api/data/classes/DS.JSONAPIAdapter.html) must have argument `query` + +Most appropriate for: +- `DS.store.queryecord()` +- `DS.store.query()` + +Gotchas: +- Requires use of `store.query()` or `store.queryRecord()`. + * The other store methods don't support `query`, i.e. `null` value passed to `userId` in `urlSegments`. +- 'Special treatment' of *apparent* query params (`this.store`) being used in the path. + * EmberData's default query methods expose adapter-level semantics by a 1:1 mapping of query (`store`) --> query string (url built by adapter). + +#### session ```javascript // adapters/comment @@ -52,6 +184,31 @@ export default DS.RESTAdapter.extend(UrlTemplates, { }); ``` +```javascript +// routes/users/user/comment +import Ember from 'ember'; + +export default Ember.Route.extend({ + model: function(params) { + let user = this.modelFor("users.user"); + return this.store.findAll('comment'); + } +}); +``` + +Usage conditions: +- Must store state in session +- Not dependent on [`DS.store`](http://emberjs.com/api/data/classes/DS.Store.html) or [Adapter](http://emberjs.com/api/data/classes/DS.JSONAPIAdapter.html). + +Most appropriate for: +- When it makes sense to store global state in a service/singleton +- Works for all `DS.store` methods + +Gotchas: +- Easy to use, but be very careful about managing URI-related application state outside of the ember router. + * Probably o.k. for a `userId`. + * Probably not o.k. for duplicating state from a URI segment, e.g. `parent//child`, with `` being stored in a session. + ## Contributing ### Installation