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

When using view.search() getting a undefined property error in QueryGenerator.js where() function #3

Open
jrcastillo opened this issue Sep 5, 2017 · 1 comment

Comments

@jrcastillo
Copy link

jrcastillo commented Sep 5, 2017

Hi Guys, I'm using this package to make full text searches in my current system. I've followed the steps on how to implement the materialized views suggested on the documentation with no luck. I'm getting the following error

TypeError: Cannot read property 'field' of undefined
    at Object.keys.forEach.key (~/proj/node_modules/pg-search-sequelize/lib/queryGenerator.js:100:59)
    at Array.forEach (native)
    at QueryGenerator.where (~/proj//node_modules/pg-search-sequelize/lib/queryGenerator.js:97:29)
    at Function.search (~/proj/node_modules/pg-search-sequelize/lib/searchModel.js:82:8)

I've been trying to debug to see if I've implemented incorrectly but, it looks very alike to the example provided. I'll post the corresponding code below:

Express router

directorsRouter.get('/search',role_auth.isAdmin, (request, response) => {
  let query =  request.query ? request.query.q : 400;

  if(query === 400) {
    return response.json({
        status: query,
    })
  } else  {
    return models.DirectorMaterializedView.searchByText(query).catch(console.log);
  }
})

User.js (reference model)

'use strict';

let SearchModel = require("pg-search-sequelize");

module.exports = (sequelize, DataTypes) => {
const user = sequelize.define('user', {
    name: {
      type: DataTypes.STRING
    },
    email: {
      type: DataTypes.STRING,
      allowNull: false,
      unique: true
    },
    password: {
      type: DataTypes.STRING,
      allowNull: false
    },
    role_id: {
      allowNull: false,
      type: DataTypes.INTEGER,
      references: {
        model: "role",
        key: "id"
      }
    },
    profile_pic: {
      type: DataTypes.STRING
    }
  });

  user.associate = (models) => {
    user.belongsTo(models.role, {
      foreignKey: 'role_id'
    })
    user.hasMany(models.director, {
      foreignKey: 'user_id',
      onDelete: 'CASCADE'
    })
    user.hasMany(models.teacher, {
      foreignKey: 'user_id',
      onDelete: 'CASCADE'
    })
    user.hasMany(models.student, {
      foreignKey: 'user_id',
      onDelete: 'CASCADE'
    })
  }

  user.hook("beforeCreate", "passwordHashing", (user, options) => {
    let hashedPassword = passwordHelper.hash(user.password)
    return user.password = hashedPassword
  })
  user.hook("afterCreate", "emailNotification", (user, options) => {
    // Asynchronous way to send an email without
    //   interrupting the flow of the system
    Mailer.sendPasswordWelcomeTemplate(user)
      .then(console.log)
      .catch(console.log)

    return user;
  })
  return user;
};

Materialized view implementation

'use strict';

const models = require("../models");

let SearchModel = require("pg-search-sequelize");

module.exports = (sequelize, DataTypes) => {
  let DirectorMaterializedView = sequelize.define('DirectorMaterializedView', {
      id: {type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true},
      name: DataTypes.STRING,
      email: DataTypes.TEXT,
      profile_pic: DataTypes.TEXT
  }, {
      tableName: 'director_materialized_view',
      timestamps: false,
      search: true,
      defaultScope: {
      attributes: {
        exclude: ['profile_pic', 'id']
        }
      },
      referenceModel: 'user' // The model for which we're defining the materialized view
  });

  return DirectorMaterializedView;
};

Index.js

fs
  .readdirSync(__dirname)
  .filter(file =>
    (file.indexOf('.') !== 0) &&
    (file !== basename) &&
    (file.slice(-3) === '.js'))
  .forEach(file => {
    const model = sequelize.import(path.join(__dirname, file));
    models[model.name] = model;
  });

Object.keys(models).forEach(key => {
  let model = models[key];
  if ('associate' in model) model.associate(models);

  if ('referenceModel' in model.options) model.referenceModel = models[model.options.referenceModel];

  if ('search' in model.options) new SearchModel(model);

  if ('customHooks' in model.options && 'afterSave' in model.options.customHooks) {
    let callback = () => model.options.customHooks.afterSave(models);
    model.afterCreate(callback);
    model.afterBulkCreate(callback);
    model.afterDestroy(callback);
    model.afterBulkDestroy(callback);
    model.afterUpdate(callback);
    model.afterBulkUpdate(callback);
  }
});

models.sequelize = sequelize;
models.Sequelize = Sequelize;

module.exports = models;

Sequelize migration

'use strict';

const QueryInterface = require("pg-search-sequelize").QueryInterface;
const models = require("../models");
const referenceModel = models.user;

const materializedViewName = "director_materialized_view";

const attributes = {
   name: "B",
   email: "A"
}

const options = {
    primaryKeyField: "id",
    include: [
        {
            model: models.director,
            foreignKey: "user_id",
            targetKey: "id",
            associationType: "hasOne", 
            attributes: { 
              phone: "D"
            }
        }
    ]
}

module.exports = {
  up: queryInterface => new QueryInterface(queryInterface).createMaterializedView(materializedViewName, referenceModel, attributes, options),

  down: queryInterface => new QueryInterface(queryInterface).dropMaterializedView(materializedViewName)
};

Any help with this will be greatly appreciated.

Extra information:

  • sequelize: 4.2.0
  • "pg-search-sequelize": "0.0.10"
  • node: 7.9.0
@reallabs
Copy link

reallabs commented Jan 9, 2018

Did you find a solution to this @jrcastillo? I am running into the same issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant