Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #102 from DouweM/keydestination

Add `keyDestination` option to complement `keySource`
  • Loading branch information...
commit 66419d75ef9a334c1a05238ec73b2ec20f21223d 2 parents b902cf2 + 6d59955
@PaulUithol authored
Showing with 62 additions and 10 deletions.
  1. +16 −2 README.md
  2. +5 −4 backbone-relational.js
  3. +41 −4 test/tests.js
View
18 README.md
@@ -146,13 +146,27 @@ For example, a Rails backend may provide the keys suffixed with `_id` or `_ids`.
1. When a relation is instantiated, the contents of the `keySource` are used as it's initial data.
2. The application uses the regular `key` attribute to interface with the relation and the models in it; the `keySource` is not available as an attribute for the model.
-3. When calling `toJSON` on a model (either via `Backbone.sync`, or directly), the data in the `key` attribute is tranformed and assigned to the `keySource`.
So you may be provided with data containing `animal_ids`, while you want to access this relation as `zoo.get( 'animals' );`.
-When saving `zoo`, the `animals` attribute will be serialized back into the `animal_ids` key.
+
+**NOTE**: for backward compatibility reasons, setting `keySource` will set `keyDestination` as well.
+This means that when saving `zoo`, the `animals` attribute will be serialized back into the `animal_ids` key.
**WARNING**: when using a `keySource`, you should refrain from using that attribute name for other purposes.
+### keyDestination
+
+Value: a string. References an attribute to serialize `relatedModel` into.
+
+Used to override `key` (and `keySource`) when determining what attribute to be written into when serializing a relation, since the server backing your relations may use different naming conventions.
+For example, a Rails backend may expect the keys to be suffixed with `_attributes` for nested attributes.
+
+When calling `toJSON` on a model (either via `Backbone.sync`, or directly), the data in the `key` attribute is transformed and assigned to the `keyDestination`.
+
+So you may want a relation to be serialized into the `animals_attributes` key, while you want to access this relation as `zoo.get( 'animals' );`.
+
+**WARNING**: when using a `keyDestination`, you should refrain from using that attribute name for other purposes.
+
### collectionType
Value: a string (which can be resolved to an object type on the global scope), or a reference to a `Backbone.Collection` type.
View
9 backbone-relational.js
@@ -276,6 +276,7 @@
this.key = this.options.key;
this.keySource = this.options.keySource || this.key;
+ this.keyDestination = this.options.keyDestination || this.options.keySource || this.key;
// 'exports' should be the global object where 'relatedModel' can be found on if given as a string.
this.relatedModel = this.options.relatedModel;
@@ -1202,21 +1203,21 @@
var value = json[ rel.key ];
if ( rel.options.includeInJSON === true && value && _.isFunction( value.toJSON ) ) {
- json[ rel.keySource ] = value.toJSON();
+ json[ rel.keyDestination ] = value.toJSON();
}
else if ( _.isString( rel.options.includeInJSON ) ) {
if ( value instanceof Backbone.Collection ) {
- json[ rel.keySource ] = value.pluck( rel.options.includeInJSON );
+ json[ rel.keyDestination ] = value.pluck( rel.options.includeInJSON );
}
else if ( value instanceof Backbone.Model ) {
- json[ rel.keySource ] = value.get( rel.options.includeInJSON );
+ json[ rel.keyDestination ] = value.get( rel.options.includeInJSON );
}
}
else {
delete json[ rel.key ];
}
- if ( rel.keySource !== rel.key ) {
+ if ( rel.keyDestination !== rel.key ) {
delete json[ rel.key ];
}
}, this );
View
45 test/tests.js
@@ -649,7 +649,7 @@ $(document).ready(function() {
ok( person.get( 'user' ).get( 'resource_uri' ) == null );
});
- test( "'keySource' loads from & saves to 'key'", function() {
+ test( "'keySource' loads from 'key", function() {
var Property = Backbone.RelationalModel.extend({
idAttribute: 'property_id'
});
@@ -689,12 +689,49 @@ $(document).ready(function() {
// The values from view.property_ids should be loaded into view.properties
ok( view.get( 'properties' ) && view.get( 'properties' ).length === 2, "'view' has two 'properties'" );
ok( typeof view.get( 'property_ids' ) === 'undefined', "'view' does not have 'property_ids'" );
+ });
+
+ test( "'keyDestination' saves to 'key'", function() {
+ var Property = Backbone.RelationalModel.extend({
+ idAttribute: 'property_id'
+ });
+ var View = Backbone.RelationalModel.extend({
+ idAttribute: 'id',
+
+ relations: [{
+ type: Backbone.HasMany,
+ key: 'properties',
+ keyDestination: 'properties_attributes',
+ relatedModel: Property,
+ reverseRelation: {
+ key: 'view',
+ keyDestination: 'view_attributes',
+ includeInJSON: true
+ }
+ }]
+ });
+
+ var property1 = new Property({
+ property_id: 1,
+ key: 'width',
+ value: 500,
+ view: 5
+ });
+
+ var view = new View({
+ id: 5,
+ properties: [ 2 ]
+ });
+
+ var property2 = new Property({
+ property_id: 2,
+ key: 'height',
+ value: 400
+ });
var viewJSON = view.toJSON();
- ok( viewJSON.property_ids && viewJSON.property_ids.length === 2, "'viewJSON' has two 'property_ids'" );
+ ok( viewJSON.properties_attributes && viewJSON.properties_attributes.length === 2, "'viewJSON' has two 'properties_attributes'" );
ok( typeof viewJSON.properties === 'undefined', "'viewJSON' does not have 'properties'" );
-
- console.log( view, viewJSON, property1, property2 );
});
test( "'collectionOptionsCallback' sets the options on the created HasMany Collections", function() {
Please sign in to comment.
Something went wrong with that request. Please try again.