balderdashy / sails

Realtime MVC Framework for Node.js
https://sailsjs.com
MIT License
22.84k stars 1.95k forks source link

Create not working on model #5934

Closed MrDHat closed 5 years ago

MrDHat commented 10 years ago

I have created an express app with waterline as the orm. My model looks like:

var User = Waterline.Collection.extend({
    identity: 'user',
    connection: 'mysql',

    autoPK: true,
    autoCreatedAt: true,
    autoUpdatedAt: true,

    attributes: {
      firstName: {
        type: 'string',
        required: true
      },
      lastName: {
        type: 'string',
      },
      phoneNumber: {
        type: 'string',
        index: true,
        unique: true
      },
      email: {
        type: 'email',
        index: true,
        unique: true
      },
      password: {
        type: 'string'
      }
    },

    // Hash passwords before saving
    beforeCreate: function(values, next) {
      bcrypt.hash(values.password, 10, function(err, hash) {
        if(err) return next(err);
        values.password = hash;
        next();
      });
    },

    toJSON: function() {
      var obj = this.toObject();
      delete obj.password;
      return obj;
    }
  });

The model is being created fine and I can see the tables in the database.

Now, I am trying to create a row in the model.

models.User.create(requestBody, function(err, user) {
        res.json({
          'status': 'CREATED',
          'code': '201',
          'success': 'User successfully created',
          'data': requestBody
        }, 201);
      });

But I get this error:

TypeError: Object function (){ return parent.apply(this, arguments); } has no method 'create'

Similar errors occur while calling find, findOne or any other query function.

tjwebb commented 10 years ago

models.User is wrong. just use User.

MrDHat commented 10 years ago

The User model actually included in a node module called models. I probably should have mentioned that in the description. Maybe some problem with the initialization or something?

tjwebb commented 10 years ago

The User model actually included in a node module called models. I probably should have mentioned that in the description. Maybe some problem with the initialization or something?

If it's not in the models/ folder, then it's not initialized as a model, it's just another object, and so it won't have the .create method or any others.

MrDHat commented 10 years ago

If it's not in the models/ folder, then it's not initialized as a model, it's just an object.

So, you mean to say that I need to include all my models in the models/ folder? (I am not using sails, btw)

This is how my structure currently looks like:

Is there a problem with such architecture?

tjwebb commented 10 years ago

Post/link your code where you initialialize your waterline collections.

MrDHat commented 10 years ago

Here:

src/index.js

var mysqlAdapter = require('sails-mysql');

var app = express();

var orm = new Waterline();

var models = require('./models')(Waterline, orm, app, mysqlAdapter, startServer);

src/models.js

module.exports = function(Waterline, orm, app, mysqlAdapter, startServer) {

  /********** ORM Settings ***************************/
  var ormConfig = {
    adapters: {
      'default': mysqlAdapter,
      mysql: mysqlAdapter
    },

    connections: {
      mysql: {
        adapter: 'mysql',
        host: 'localhost',
        database: 'dbName',
        user: 'user',
        password: 'password'
      }
    },

    defaults: {
      migrate: 'alter'
    }
  };
  /************* End ORM settings *********************/

  /************* Model imports *************************/

  var users = require('./users/models')(Waterline, orm, app);

  /************* End Model imports *********************/

  // Start Waterline
  orm.initialize(ormConfig, function(error, models) {
    if (error) {
      throw error;
    }

    app.models = models.collections;
    app.connections = models.connections;

    startServer();

  });

  // Return public models
  return {
    users: users
  };

};

Also src/users/models.js contains orm.loadCollection(User);

PS: The tables are being created fine in the database.

tjwebb commented 10 years ago
app.models = models.collections;

So don't you need to use app.models instead of just models?

var models = require('./models')(Waterline, orm, app, mysqlAdapter, startServer);

This won't work. Your function is asynchronous, but you're treating it like its synchronous.

I don't think your issues are with Waterline.

tjwebb commented 10 years ago

Also, you're building an app with express and waterline. That's exactly what sails.js is. You should just use that instead of re-inventing the wheel.

MrDHat commented 10 years ago

Right, I get the problem now. Thanks!

MrDHat commented 10 years ago

I am considering sails on your advice. I am planning to use a nosql database like cassandra as the secodary data storage. How well does it fill in the sails ecosystem? Is it on the waterline roadmap? If not, is there a documentation somewhere which can enable me to build the cassandra adapter myself?

Also, is it possible to use express middlewares with sails without any hassle?