Sails.js中出现Article.find() is not a function的TypeError报错
Sails.js 调用Articles.find()报"not a function"的排查与修复
核心报错成因
- 手动通过
require引入models目录下的模型文件时,拿到的只是纯模型定义配置对象,并非Waterline ORM初始化完成后、绑定了完整查询能力(find/create/update等)的可操作模型实例,因此不存在find()方法。 - Sails的模型加载逻辑不会将models目录的文件自动注入Controller作用域,所有模型会在应用启动阶段自动挂载到全局
sails.models对象上,作为可直接调用的操作实例。
分步修复方案
- 移除Controller中手动引入模型的代码
删掉ArticleController.js内的const Articles = require("../models/Articles");行:一方面当前项目不存在名为Articles.js的模型文件,手动require的路径本身就不匹配;另一方面这种引入方式拿到的对象不具备ORM操作能力。 - 通过全局挂载的sails实例获取已初始化的模型
Sails模型的全局挂载规则为:models目录下的模型文件名(去掉.js后缀)转全小写后,会作为键绑定到sails.models对象上。当前项目的模型文件为Article.js,对应的挂载键为article,直接在Controller的action逻辑内取值即可,修正后的代码示例:// ArticleController.js module.exports = { list: (req, res) => { // 从全局sails实例获取完成初始化的模型 const Articles = sails.models.article Articles.find().exec((err, articles) => { if (err) { return res.status(500).json({ err: err }); } res.view('articles/articles', { articles: articles }); }) } }提示:如果不想依赖全局sails对象,也可以通过请求上下文携带的sails实例取值:
const Articles = req._sails.models.article,效果完全一致。 - 校验datastore配置结构
确认数据库连接配置存放在config/datastores.js文件内,且严格遵循Sails的规范导出结构,不要将datastore配置直接暴露在配置文件根层级:// config/datastores.js 标准结构示例 module.exports = { datastores: { mongodb: { adapter: require('sails-mongo'), url: 'mongodb://localhost:27017/articlebase' } } } - 确认模型的datastore绑定匹配
模型文件中配置的datastore: 'mongodb',需要和datastores配置内的键名完全一致(大小写、拼写无偏差),否则模型无法正常绑定数据库连接,也会出现查询方法异常的问题。
常见避坑提醒
- 不要在应用启动的同步流程内(比如config/bootstrap.js的最外层、文件加载阶段)直接引用
sails.models上的模型,此时ORM还未完成初始化,拿到的对象同样不具备查询方法;所有请求触发的Controller逻辑内,模型已经完成初始化,可以正常调用。 - 手动require models目录下的定义文件时,拿到的对象仅包含静态的attributes、配置项内容,没有绑定任何Waterline查询方法,不要用这种方式替代全局挂载的模型实例。
内容的提问来源于stack exchange,提问作者user3671390
相关产品推荐
相关产品推荐

