Permalink
Browse files

Coerce attributes into specified types.

  • Loading branch information...
benpickles committed Apr 13, 2010
1 parent 90db564 commit f74cc8f66a19b0fd088fe19ca584a68eb6cf1341
Showing with 66 additions and 1 deletion.
  1. +1 −1 src/model.js
  2. +32 −0 src/model_instance_methods.js
  3. +33 −0 test/tests/model.js
View
@@ -4,7 +4,7 @@ var Model = function(name, class_methods, instance_methods) {
// The model constructor.
var model = function(attributes) {
- this.attributes = jQuery.extend({}, attributes)
+ this.attributes = this.coerceAttributes(jQuery.extend({}, attributes))
this.changes = {};
this.errors = new Model.Errors(this);
this.uid = [name, Model.UID.generate()].join("-")
@@ -4,6 +4,8 @@ Model.InstanceMethods = {
// Combined attributes/changes object.
return jQuery.extend({}, this.attributes, this.changes);
} else if (arguments.length === 2) {
+ value = this.coerceAttribute(name, value)
+
// Don't write to attributes yet, store in changes for now.
if (this.attributes[name] === value) {
// Clean up any stale changes.
@@ -72,6 +74,36 @@ Model.InstanceMethods = {
}
},
+ coerceAttribute: function(name, value) {
+ var type = this.constructor.attribute_types && this.constructor.attribute_types[name]
+
+ if (type) {
+ switch (type) {
+ case "boolean":
+ value = (
+ value === false || value === "false" ||
+ value === 0 || value === "0"
+ ) ? false : true
+ break
+ case "float":
+ value = parseFloat(value)
+ break
+ case "integer":
+ value = parseInt(value)
+ break
+ }
+ }
+
+ return value
+ },
+
+ coerceAttributes: function(attributes) {
+ for (var name in attributes) {
+ attributes[name] = this.coerceAttribute(name, attributes[name])
+ }
+ return attributes
+ },
+
destroy: function(callback) {
this.callPersistMethod("destroy", callback);
return this;
View
@@ -82,6 +82,39 @@ test("attr, attributes, changes, reset, save, destroy", function() {
});
});
+test("attribute types", function() {
+ var Post = Model("post", {
+ attribute_types: {
+ category_id: "integer",
+ lat: "float",
+ published: "boolean"
+ }
+ })
+
+ var post = new Post({
+ category_id: "1.4",
+ lat: "12345.6789",
+ published: "false"
+ })
+
+ ok(post.attr("category_id") === 1)
+ ok(post.attr("lat") === 12345.6789)
+ ok(post.attr("published") === false)
+
+ post.attr("published", true)
+ ok(post.attr("published") === true)
+ post.attr("published", 0)
+ ok(post.attr("published") === false)
+ post.attr("published", "true")
+ ok(post.attr("published") === true)
+ post.attr("published", "0")
+ ok(post.attr("published") === false)
+ post.attr("published", 1)
+ ok(post.attr("published") === true)
+ post.attr("published", false)
+ ok(post.attr("published") === false)
+})
+
test("custom methods", function() {
var Post = Model("post", {
foo: function() {

0 comments on commit f74cc8f

Please sign in to comment.