Skip to content

Commit

Permalink
Merge pull request #9 from Oktavilla/selective-foreign-key-use
Browse files Browse the repository at this point in the history
Be selective about when to use foreign keys for mapping properties
  • Loading branch information
snurra authored Mar 10, 2017
2 parents 6278fff + 9afba2b commit dba6ca3
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 8 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,9 @@ var MyStrictModel = Backbone.StrictModel.extend({
});
```

In the example above, doing `set("firstName", "Göran")` will result in `{ "name": "Göran" }`
However, if you do `set({ "firstName": "Göran", "name": "Göran Smöran" })` firstName will be ignored and the data in `name` will be used instead.
In the example above, doing `new MyStrictModel({ firstName: "Göran" })` will
result in a model with `{ "name": "Göran" }`. However, when just setting
properties, you will need to be explicit about wanting to use the foreign
mappings. For example, `myModelInstance.set({ firstName: "Sven" })` will have
no effect on the model instance, but
`myModelInstance.set({ firstName: "Sven" }, { useForeignKeys: true })` will.
30 changes: 24 additions & 6 deletions backbone-despotism.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@
* }
* }
*
* In the example above, doing `set("firstName", "Göran")` will result in { "name": "Göran" }.
* However, if you do `set({ "firstName": "Göran", "name": "Göran Smöran" })` firstName will be ignored.
* In the example above, doing `new MyStrictModel({ firstName: "Göran" })` will result in a model
* with `{ "name": "Göran" }`. However, when just setting properties, you will need to be
* explicit about wanting to use the foreign mappings. For example, `myModelInstance.set({ firstName: "Sven" })`
* will have no effect on the model instance, but
* `myModelInstance.set({ firstName: "Sven" }, { useForeignKeys: true })` will.
*/
(function(root, factory) {
"use strict";
Expand All @@ -42,6 +45,15 @@
}
} (this, function(exports, Backbone, _) {
Backbone.StrictModel = Backbone.Model.extend({
constructor: function(attributes, options) {
// Make sure that the options object when initializing a new instance of
// the StrictModel always has { initialize: true }
attributes = attributes || {};
options = options || {};
options.initialize = true;
return Backbone.Model.call(this, attributes, options);
},

set: function(key, value, options) {
var attrs;
if (key === null) {
Expand All @@ -55,7 +67,7 @@
(attrs = {})[key] = value;
}
if (this.props) {
attrs = mapAttributes(attrs, this.props, this.defaults);
attrs = mapAttributes(attrs, this.props, this.defaults, options);
}
return Backbone.Model.prototype.set.apply(this, [attrs, options || {}]);
},
Expand All @@ -73,12 +85,18 @@
}
});

function mapAttributes (json, props, defaults) {
function mapAttributes (json, props, defaults, options) {
var attributes = {};
options || (options = {});
_.each(props, function(definition, key) {
// Foreign key (if it exists) should only be used if the key does not exist in the json or it has the default value
var foreignKey = (definition.foreignKey && (typeof json[key] === "undefined" || (defaults && json[key] === defaults[key] && typeof json[definition.foreignKey] !== "undefined"))) ? definition.foreignKey : key;
var foreignKey = key;
var type = definition.type || definition;
// Foreign keys should only be used on initialization of the model, or if
// specifically requested
if (options.useForeignKeys || options.initialize || options.reset) {
// Foreign key (if it exists) should only be used if the key does not exist in the json or it has the default value
foreignKey = (definition.foreignKey && (typeof json[key] === "undefined" || (defaults && json[key] === defaults[key] && typeof json[definition.foreignKey] !== "undefined"))) ? definition.foreignKey : key;
}
// Check that this property exists in the json, and import it if so...
if (json[foreignKey] !== undefined && typeof json[foreignKey] === type) {
attributes[key] = json[foreignKey];
Expand Down

0 comments on commit dba6ca3

Please sign in to comment.