Coder Social home page Coder Social logo

backbone-mongo's Introduction

Build Status

logo

BackboneMongo provides MongoDB storage for BackboneORM.

Because BackboneORM's query language is based on MongoDB's query language, many queries just work! With a twist...Backbone.ORM provides cross-collection relationships and embedded data for MongoDB.

In addition, BackboneMongo using CouchDB-style '_rev' versioning to ensure coherency of data.

Examples (CoffeeScript)

class Change extends Backbone.Model
  model_name: 'Change'
  sync: require('backbone-orm').sync(Change)

class Task extends Backbone.Model
  urlRoot: 'mongodb://localhost:27017/tasks'
  schema:
    project: -> ['belongsTo', Project]
    changes: -> ['hasMany', Change, embed: true]
  sync: require('backbone-mongo').sync(Task)

class Project extends Backbone.Model
  urlRoot: 'mongodb://localhost:27017/projects'
  schema:
    tasks: -> ['hasMany', Task]
    changes: -> ['hasMany', Change, embed: true]
  sync: require('backbone-mongo').sync(Project)

Examples (JavaScript)

var Change = Backbone.Model.extend({
  model_name: 'Change',
});
Task.prototype.sync = require('backbone-orm').sync(Change);

var Task = Backbone.Model.extend({
  urlRoot: 'mongodb://localhost:27017/tasks',
  schema: {
    project: function() { return ['belongsTo', Project]; }
    changes: function() { return ['hasMany', Change, {embed: true}]; }
  }
});
Task.prototype.sync = require('backbone-mongo').sync(Task);

var Project = Backbone.Model.extend({
  urlRoot: 'mongodb://localhost:27017/projects',
  schema: {
    tasks: function() { return ['hasMany', Task]; }
    changes: function() { return ['hasMany', Change, {embed: true}]; }
  }
});
Project.prototype.sync = require('backbone-mongo').sync(Project);

Please checkout the website for installation instructions, examples, documentation, and community!

For Contributors

To build the library for Node.js:

$ gulp build

Please run tests before submitting a pull request:

$ gulp test --quick

and eventually all tests:

$ npm test

backbone-mongo's People

Contributors

gwilymhumphreys avatar kmalakoff avatar kvnloo avatar toddself avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

backbone-mongo's Issues

Fix intermittent test failures

Two hypotheses:

  1. they are due to test setup and cleanup not being perfect when option variants are being run one after another

  2. they are due to a sequence returning incorrectly like MemoryCursor.buildFindQuery needing to merge query parameters

  1) hasMany (cache: undefined, query_cache: undefined, embed: true) Can manually delete a relationship by related_model (belongsTo) with unloaded model:
     Uncaught AssertionError: loaded correct model

  2) hasMany (cache: undefined, query_cache: undefined, embed: true) Can manually delete a relationship by array of related_model (belongsTo) with unloaded model:
     Uncaught AssertionError: loaded correct model

  3) hasMany (cache: undefined, query_cache: undefined, embed: true) Can query on related (one-way hasMany) models with included relations:
     Uncaught AssertionError: found model

Multiple calls to Model#set don't cause change triggers to fire

Hopefully I'm not missing anything here :)

'use strict';

var Backbone = require('backbone');
var mongoSync = require('backbone-mongo').sync;

var ManyModel = Backbone.Model.extend({
  urlRoot: 'mongodb://localhost:27017/many_model'
});
ManyModel.prototype.sync = mongoSync(ManyModel);

var MainModel = Backbone.Model.extend({
  urlRoot: 'mongodb://localhost:27017/main_model',

  schema: {
    many: ['manyToMany', ManyModel]
  },

  initialize: function(){
    this.on('change:many', function(model, val){
      console.log('trying to change many');
    });
  }
});
MainModel.prototype.sync = mongoSync(MainModel);

var main = new MainModel();
var many = new ManyModel({foo: 'bar'});

// this works as expected, logs "trying to change many"
main.set('many', [many]);

var manyCollection = main.get('many');
manyCollection.push(c);

// this doesn't console.log
main.set('many', manyCollection);

// this doesn't log either
main.set('many', [many]);

main._events['change:many'][0].callback.toString()
'function (model, val){\nconsole.log(\'trying to change many\');\n}'

Also, is there a way to hide attributes from the backbone-rest system? I see there is some documentation on templates, but I didn't see any information on how they work other than the quick examples.

toJSON doesn't serialize attached models

Example:

var Backbone = require('backbone');
var mongoSync = require('backbone-mongo').sync;

var Inner = Backbone.Model.extend({
    urlRoot: 'mongodb://localhost:27017/inner'
});
Inner.prototype.sync = mongoSync(Inner);

var Outer = Backbone.Model.extend({
    urlRoot: 'mongodb://localhost:27017/outer',
   schema: {
        inner: function(){
            return ['hasOne', Inner];
        }
    }
});
Outer.prototype.sync = mongoSync(Outer);

var outer = new Outer();
outer.set({foo: 'bar', inner: new Inner({fie: 'baz'})});
{ cid: 'c5',
  attributes:
   { howdy: 'ho',
     inner:
      { cid: 'c10',
        attributes: [Object],
        _changing: false,
        _previousAttributes: {},
        changed: {},
        _pending: false,
        _orm: [Object] } },
  changed:
   { inner:
      { cid: 'c10',
        attributes: [Object],
        _changing: false,
        _previousAttributes: {},
        changed: {},
        _pending: false,
        _orm: [Object] } },
  _orm:
   { needs_load: {},
     is_initialized: true,
     rel_dirty: { inner: true } },
  _changing: false,
  _previousAttributes: { howdy: 'ho' },
  _pending: false }

outer.get('inner');
{ cid: 'c10',
  attributes: { fie: 'baz' },
  _changing: false,
  _previousAttributes: {},
  changed: {},
  _pending: false,
  _orm: { needs_load: {}, is_initialized: true } }

outer.toJSON();
{foo: 'bar'}

Expected:

outer.toJSON();
{
    foo: 'bar',
    inner: {
        fie: 'baz'
    }
}

After an error emitted by mongo, queries do not return

When mongodb encounters some classes of errors, it will close its connection. After this happens, every query that BackboneORM executes against that collection will not call its callback at all. Ideally, BackboneORM should listen for the error event and reconnect.

Following is the error that exposed this issue:

parseError occured
  at [object Object].<anonymous> (./node_modules/mongodb/lib/mongodb/connection/connection_pool.js:182:34)
  at [object Object].EventEmitter.emit (events.js:98:17)
  at Socket.<anonymous> (./node_modules/mongodb/lib/mongodb/connection/connection.js:389:20)
  at Socket.EventEmitter.emit (events.js:95:17)
  at Socket.<anonymous> (_stream_readable.js:746:14)
  at Socket.EventEmitter.emit (events.js:92:17)
  at emitReadable_ (_stream_readable.js:408:10)
  at emitReadable (_stream_readable.js:404:5)
  at readableAddChunk (_stream_readable.js:165:9)
  at Socket.Readable.push (_stream_readable.js:127:10)
  at TCP.onread (net.js:526:21)

Promise feature request

It would be nice if this library could be used with promises.

Also a request for a formal doc to promisify the sync method with bluebird.

MongoDB connection remains open

Script execution never finished since connection remains open.
Tried to close connection calling destroy (which will remove sync handler from model too) but even that did not help.

var Word = require('../../models/word');
var assert = require('assert');

var word = new Word({asd: 'qwe'});

word.save({
  success: function(project) {
    debugger;
    return console.log("We're saved!");
  },
  error: function(project, err) {
    debugger;
    return console.log('Oh no an error');
  }
});

//Word.prototype.sync('destroy');

Am I doing something wrong here?

Frontpage example has error?

I'm new to this area so it might be a spurious claim. However, it sure looks like the line in your first frontpage javascript example which reads...

Task.prototype.sync = require('backbone-orm').sync(Change);

...should actually read...

Change.prototype.sync = require('backbone-orm').sync(Change);

Nested attributes don't save and fetch as expected

I could be doing it wrong, but I would expect the following to work:

var Backbone = require('backbone');
var assert = require('assert');

var InnerModel = Backbone.Model.extend({
   urlRoot: '/innermodel'
});
InnerModel.prototype.sync = require('backbone-orm').sync(InnerModel);

var OuterModel = Backbone.Model.extend({
    urlRoot: 'mongodb://localhost:27017/testModel',
    schema: {
        innerModel: function(){
            return ['hasOne', InnerModel, {embed: true}];
        }
    }
});
OuterModel.prototype.sync = require('backbone-mongo').sync(OuterModel);

var om = new OuterModel({foo: 'bar', innerModel: new InnerModel({bar: 'baz'})});
om.save(function(err, om){
    if(err) return err;
    var om2 = new OuterModel({id: om.id});
    om2.fetch(function(om2){
       assert.deepEqual(om2.get('innerModel').attributes, om.get('innerModel').attributes);
    });
});

Errors out with:

TypeError: Cannot call method 'get' of null
    at repl:5:23
    at /Users/todd/src/conde/fauxpilot/node_modules/backbone-mongo/node_modules/backbone-orm/lib/utils.js:108:16
    at Object.success (/Users/todd/src/conde/fauxpilot/node_modules/backbone-mongo/node_modules/backbone-orm/lib/utils.js:92:18)
    at /Users/todd/src/conde/fauxpilot/node_modules/backbone-mongo/node_modules/backbone-orm/lib/extensions/model.js:407:66
    at /Users/todd/src/conde/fauxpilot/node_modules/backbone-mongo/node_modules/backbone-orm/lib/utils.js:108:16
    at success (/Users/todd/src/conde/fauxpilot/node_modules/backbone-mongo/node_modules/backbone-orm/lib/utils.js:92:18)
    at Object.options.success (/Users/todd/src/conde/fauxpilot/node_modules/backbone/backbone.js:433:22)
    at /Users/todd/src/conde/fauxpilot/node_modules/backbone-mongo/lib/sync.js:77:26
    at /Users/todd/src/conde/fauxpilot/node_modules/backbone-mongo/node_modules/backbone-orm/lib/cursor.js:236:22
    at QueryCache.module.exports.QueryCache.set

Because om2.get('innerModel') is null. Expected it to be the innerModel instance generated when om was generated.

It looks like since toJSON doesn't handle nested models correctly, the create method on line 63 of src/sync.coffee returns no data for the nested attribute.

Can't have it working with node.js modules

Trying to use it as described in example with getting errors when model required second time.

var Backbone = require('backbone');

module.exports = Backbone.Model.extend({
    urlRoot: 'mongodb://localhost:27017/words',
    schema: {
        id: {
            indexed: true
        }
    }
});

// module.exports.model_type_id = 'Word'; (workaround for the problem)
module.exports.prototype.sync = require('backbone-mongo').sync(module.exports);

Getting such an error

throw new Error("Duplicate model name / url combination: " + model_typ

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.