Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #91: Add Backbone.RelationalModel.setup method to set up reverse relations etc. when not using .extend. (CoffeeScript!) #112

Merged
merged 9 commits into from
May 16, 2012
64 changes: 57 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Backbone-relational depends on [backbone](https://github.com/documentcloud/backb
<script type="text/javascript" src="./js/backbone-relational.js"></script>
```

Backbone-relational has been tested with Backbone 0.9.0 (or newer) and Underscore 1.3.1 (or newer).
Backbone-relational has been tested with Backbone 0.9.2 (or newer) and Underscore 1.3.1 (or newer).


## <a name="backbone-relation"/>Backbone.Relation options
Expand Down Expand Up @@ -225,7 +225,7 @@ It's only mandatory to supply a `key`; `relatedModel` is automatically set. The

## <a name="backbone-relationalmodel"/>Backbone.RelationalModel

`Backbone.RelationalModel` introduces a couple of new methods and events.
`Backbone.RelationalModel` introduces a couple of new methods, events and properties.

### Methods

Expand Down Expand Up @@ -254,6 +254,56 @@ See the example at the top of [Backbone.Relation options](#backbone-relation) or
* `update`: triggered on changes to the key itself on `HasMany` and `HasOne` relations.
Bind to `update:<key>`; arguments: `(model<Backbone.Model>, related<Backbone.Model|Backbone.Collection>)`.

### Properties

Properties can be defined along with the subclass prototype when extending `Backbone.RelationalModel` or a subclass thereof.

###### <a name="property-part-of-supermodel" />**partOfSupermodel**

Value: a boolean. Default: `false`.

Determines whether this model should be considered a proper submodel of its
superclass (the model type you're extending), with a shared id pool.

This means that when looking for an object of the supermodel's type, objects
of this submodel's type could be returned as well, as long as the id matches.
In effect, any relations pointing to the supermodel will look for objects
of the supermodel's submodel's types as well.

Suppose that we have an `Animal` model and a `Dog` model extending `Animal`
with `partOfSupermodel` set to `true`. If we have a `Dog` object with id `3`,
this object will be returned when we have a relation pointing to an `Animal`
with id `3`, as `Dog` is regarded a specific kind of `Animal`: it's just an
`Animal` with possibly some dog-specific properties or methods.

Note that this means that there cannot be any overlap in ids between instances
of classes `Animal` and `Dog`, as the `Dog` with id `3` will *be* the `Animal`
with id `3`.

###### <a name="property-submodel-type" />**submodelType**

Value: a string.

When building a model instance for a relation with a `relatedModel` that has
one or more submodels (i.e. models that have
[`partOfSupermodel`](#property-part-of-supermodel) set to true), we need to
determine what kind of object we're dealing with and an instance of what
submodel should be built. This is done by finding the `relatedModel`'s
submodel for which the `submodelType` is equal to the value of the
[`submodelTypeAttribute`](#property-submodel-type-attribute) attribute on the
newly passed in data object.

###### <a name="property-submodel-type-attribute" />**submodelTypeAttribute**

Value: a string. References an attribute on the data used to instantiate
`relatedModel`. Default: `"type"`.

The attribute that will be checked to determine the type of model that
should be built when a raw object of attributes is set as the related value,
and if the `relatedModel` has one or more submodels.

See [`submodelType`](#property-submodel-type) for more information.

## <a name="example"/>Example

```javascript
Expand Down Expand Up @@ -386,25 +436,25 @@ User = Backbone.RelationalModel.extend();

## <a name="q-and-a"/>Known problems and solutions

> **Q:** (Reverse) relations don't seem to be initialized properly (and I'm using Coffeescript!)
> **Q:** (Reverse) relations or submodels don't seem to be initialized properly (and I'm using CoffeeScript!)

**A:** You're probably using the syntax `class MyModel extends Backbone.RelationalModel` instead of `MyModel = Backbone.RelationalModel.extend`.
This has advantages in CoffeeScript, but it also means that `Backbone.Model.extend` will not get called.
Instead, CoffeeScript generates piece of code that would normally achieve roughly the same.
However, `extend` is also the method that Backbone-relational overrides to set up relations as soon as your code gets parsed by the JavaScript engine.
However, `extend` is also the method that Backbone-relational overrides to set up relations and other things as you're defining your `Backbone.RelationalModel` subclass.

A possible solution is to initialize a blank placeholder model right after defining a model that contains reverseRelations; this will also bootstrap the relations. For example:
For exactly this scenario where you're not using `.extend`, `Backbone.RelationalModel` has the `.setup` method, that you can call manually after defining your subclass CoffeeScript-style. For example:

```javascript
class MyModel extends Backbone.RelationalModel
relations: [
// etc
]

new MyModel
MyModel.setup()
```

See [issue #91](https://github.com/PaulUithol/Backbone-relational/issues/91) for more information and workarounds.
See [issue #91](https://github.com/PaulUithol/Backbone-relational/issues/91) for more information.

> **Q:** After a fetch, I don't get `add:<key>` events for nested relations.

Expand Down
Loading