Models

Victor Bjelkholm edited this page Feb 16, 2014 · 5 revisions

Overview

Geddy models work similarly to the model component in ORMs like DataMapper, ActiveRecord, SQLAlchemy, or Django’s models. The biggest difference is there is no query API ~~- Geddy’s models are very minimal, providing a structure for defining a model, and validating the properties on model-instances.
With Geddy models, the models are defined in the model files, not in a database schema. \

Generating resources

Use geddy resource <name> [model properties] to generate a resource in your application. Resources do not generate views, but creates a view directory. A resource route will be created for you.

mde@localhost:~/work$ geddy resource snow_dog breed:string name:string color:string
[Added] app/models/snow_dog.js
[Added] app/controllers/snow_dogs.js
[Added] Resource snow_dogs route added to config/router.js
[Added] snow_dogs view directory
```

Now start your Geddy server and your new route will work. Trying this for example
will return the params for the index action in JSON:

```
$ curl localhost:4000/snow_dogs.json
{"params":{"method":"GET","controller":"SnowDogs","action":"index","format":"json"}}
```

Geddy generators handle plural inflections for model and controller names. ex: 'person' to 'people'
To read about the model properties argument jump to [Model properties](#model-properties)

### Generating scaffolding

Use `geddy scaffold <name> [model properties]` to generate scaffoling in your application.
Scaffolding creates full CRUD actions including views. Resource routes will be created for you.

mde@localhost:~/work$ geddy resource snow_dog breed:string name:string color:string [Added] app/models/snow_dog.js [Added] app/controllers/snow_dogs.js [Added] Resource snow_dogs route added to config/router.js [Added] View templates


Now start your Geddy server and you'll have new views created from scaffolding. Trying this for example
will return the content for the index action in HTML:

$ curl localhost:4000/snow_dogs

<title>Geddy App | This app uses Geddy.js</title>
<meta name="viewport" content="width=device-width" />

<!-- The HTML5 shim, for IE6-8 support of HTML elements -->
<!--[if lt IE 9]>
  <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

.....


Geddy generators handle plural inflections for model and controller names. ex: 'person' to 'people'
To read about the model properties argument jump to [Model properties](#model-properties)

### Model properties

Some Geddy generators (resource, scaffold and model) have a argument that takes a list of model
properties. Here's an example of a resource with some properties:

geddy resource user name admin:boolean lastLogin:datetime


Each of these items include a name and an optional type, if there's no type given it'll default
to string. The list of supported types are listed in the properties documentation below.

You can also use custom default properties:

geddy resource user name:default admin:boolean

The above example will use the property `name`(string) to display the items in the views instead of the default ID property, this way when generating scaffolds, it will look better out of the box.

Defining your model
-------------------

A basic model looks like this:

    var SnowDog = function () {
    };
    SnowDog = geddy.model.register('SnowDog', SnowDog);

### Properties

You can add properties with the ‘property’ method.

    var SnowDog = function () {
      this.property('foo', 'string' {required: true});
      this.property('bar', 'string' {length: {min: 3}});
      this.property('baz', 'number');
      this.property('qux', 'boolean');
    };
    SnowDog = geddy.model.register('SnowDog', SnowDog);

Datatypes supported include:

-   string
-   number
-   int
-   boolean
-   object
-   datetime
-   date
-   time

There are currently two triggers you can pass as options to your
‘property’ calls that will add validations:

-   required ~~- Set to true, will create a validatesPresent
    validation.\
    \* length~~- Can be passed an exact number or a key/value object
    with ‘min’ and ‘max’ properties. This will create a validatesLength
    validation.

### Validations

You can create validations for different properties:

    var SnowDog = function () {
      this.property('foo', 'string');
      this.property('bar', 'string');
      this.property('baz', 'number');
      this.property('qux', 'boolean');
      this.validatesPresent('foo');
      this.validatesLength('bar', {min: 3});
    };
    SnowDog = geddy.model.register('SnowDog', SnowDog);

Validations supported are:

-   validatesPresent(fieldName);
-   validatesFormat(fieldName, regExp);
-   validatesLength(fieldName, [length or object with min/max keys]);
-   validatesConfirmed(fieldName, confirmFieldName);
-   validatesWithFunction(fieldName, functionThatReturnsTrueOrFalse);

### Methods

You can define methods either directly in the constructor function for
your model, or hang them on the prototype:

    var SnowDog = function () {
      this.property('foo', 'string');
      this.property('bar', 'string');
      this.property('baz', 'number');
      this.property('qux', 'boolean');
      this.validatesPresent('foo');
      this.validatesLength('bar', {min: 3});
      // Instances will get this method
      this.someMethod = function () {
      };
    };
    // Instances get this one too
    SnowDog.prototype.someOtherMethod = function () {
    };
    SnowDog = geddy.model.register('SnowDog', SnowDog);

CRUD with model-items
---------------------

### Create

Use the static ‘create’ method on your model:

    var params = {foo: 'asdf', bar: 'qwer'};
    var dog = SnowDog.create(params);

If all your datatypes are sane, and all validations pass, you have a
shiny new instance of SnowDog you can save. If something isn’t right
with the params you pass, you’ll find an ‘errors’ property on your
model-item instance.

The ‘errors’ object is a key/value object with a key for each field name
that didn’t validate, with a value of the error message for the problem.

Trying to create a SnowDog with a ‘baz’ property that’s not a number
will give you:

    var params = {foo: 'asdf', bar: 'qwer', baz: 'howdy'};
    var dog = SnowDog.create(params);
    dog.errors.baz // => Field "baz" must be a number