如何创build一个正常的风帆模型,而不在模型文件夹

所以,

我正在为我的应用程序实现一个插件API,插件可以有自己的模型,想象一下。

SimplePlugin = { pluginName: 'simple', pluginConfig: {}, SimpleModel: { attributes: { name: 'string' } } } 

所以我需要能够创build一个“一次性”的模型,只要有需要的function,它需要具有完全相同的function,因此您自动得到的URL像/simplePlugin/:idfind /simplePlugin/:id

谢谢

在目前的项目状态下,你试图做的事情并不容易,也不太方便。 我指的是v0.10版本。 你需要做的是

  1. 将在SimplePlugin.SimpleModelfind的模型定义注入到sails.models中
  2. _config: { rest: true }为模型注入虚拟控制器

请注意,我发布的代码示例取自我正在处理的自定义Sails钩子,并假定可以访问loadHooks以及在Sails初始化的loadHooks阶段/ MiddlewareRegistry阶段之前执行的代码示例(比较: lib / app / load.js )。

1.注入模型定义

在Sails v0.10 的orm钩子中提示之后,你必须:

  • 获取api定义的模型和适配器,将新模型合并到字典中
  • 通过sails.hooks.orm.normalizeModelDef规范化模型定义
  • 将标准化的模型定义加载到水线
  • 通过teardown卸载现有的适配器连接
  • 重新初始化水线
  • 通过sails.hooks.orm.prepareModels (先前: sails.hooks.orm.exposeModels ,更改为: 8d96895662 )将初始化的Waterline集合公开到全局范围,

因为你必须重新初始化水线并重新加载所有的模型定义,我build议收集所有的模型定义来注入并将它们传递给注入函数一次。 下面的示例代码反映了这一点。

 ... function injectPluginModels(pluginModels, cb) { // copy sails/lib/hooks/orm/loadUserModules to make it accessible here var loadUserModelsAndAdapters = require('./loadUserModules')(sails); async.auto({ // 1. load api/models, api/adapters _loadModules: loadUserModelsAndAdapters, // 2. Merge additional models, 3. normalize model definitions modelDefs: ['_loadModules', function(next){ _.each(additionModels, function(aditionModel) { _.merge(sails.models, additionalModel); }); _.each(sails.models, sails.hooks.orm.normalizeModelDef); next(null, sails.models); }], // 4. Load models into waterline, 5. tear down connections, 6. reinitialize waterline instantiatedCollections: ['modelDefs', function(next, stack){ var modelDefs = stack.modelDefs; var waterline = new Waterline(); _.each(modelDefs, function(modelDef, modelID){ waterline.loadCollection(Waterline.Collection.extend(modelDef)); }); var connections = {}; _.each(sails.adapters, function(adapter, adapterKey) { _.each(sails.config.connections, function(connection, connectionKey) { if (adapterKey !== connection.adapter) return; connections[connectionKey] = connection; }); }); var toTearDown = []; _.each(connections, function(connection, connectionKey) { toTearDown.push({ adapter: connection.adapter, connection: connectionKey }); }); async.each(toTearDown, function(tear, callback) { sails.adapters[tear.adapter].teardown(tear.connection, callback); }, function(){ waterline.initialize({ adapters: sails.adapters, connections: connections }, next) }); }], // 7. Expose initialized models to global scope and sails _prepareModels: ['instantiatedCollections', sails.hooks.orm.prepareModels] }, cb); }; ... 

可以让你:

 // Read your plugins ... var pluginModels = // Get all the plugin models injectPluginModels(pluginModels, function(){ // Plugin models now available via global[pluginModel.globalId] and sails.models[pluginModel.identity] }); 

2.注入控制器

对于每个应通过蓝图方法公开的模型,您必须:

  • 创build一个匹配的身份和启用蓝图的控制器定义
  • 将控制器保存到sails.controllers[controllerId]
  • 将控制器保存到sails.hooks.controllers.middleware[controllerId]

Sails MiddlewareRegistry将自动选取在这些对象中find的控制器。

 function mountBlueprintsForModels(pluginModels) { _.each(pluginModels, function(pluginModel){ var controller = _.cloneDeep(pluginModel); controller._config = { rest: true }; var controllerId = pluginModel.identity; if (!_.isObject(sails.controllers[controllerId])) { sails.controllers[controllerId] = controller; } if (!_.isObject(sails.hooks.controllers.middleware[controllerId])) { sails.hooks.controllers.middleware[controllerId] = controller; } }); } 

3.在行动

 // Eg in /api/hooks/plugins/index.js /* * Module dependencies */ var async = require('async'), _ = require('lodash'), waterline = require('waterline'); module.exports = function(sails) { // injectPluginModels and mountBlueprintsForModels defined here ... return { initialize: function(cb) { sails.after('hook:orm:loaded', function() { yourNiftyPluginLoader(function(err, plugins) { // assuming plugin.models holds array of models for this plugin // customize for your use case var pluginModels = _.pluck(plugins, 'models'); injectPluginModels(pluginModels, cb); mountBlueprintsForModels(pluginModels); }); }); } } } 

编辑:不完全工作,因为集合被分配到初始化连接。

似乎有一个更好的解决scheme,有3行代码,不需要断开/重新连接数据库。 我刚刚研究了Waterline的源代码(请参阅https://github.com/balderdashy/waterline/blob/master/lib/waterline.js#L109 )。 可以这样做:

 var Waterline = require('waterline'); // Other dependencies var Schema = require('waterline-schema'); var CollectionLoader = require('waterline/lib/waterline/collection/loader'); var orm = new Waterline(); var config = { // Setup Adapters // Creates named adapters that have have been required adapters: { 'default': 'mongo', mongo: require('sails-mongo') }, // Build Connections Config // Setup connections using the named adapter configs connections: { 'default': { adapter: 'mongo', url: 'mongodb://localhost:27017/sausage' } } }; orm.initialize(config, function(err, data) { if (err) { throw err; } // ORM initialized, let's add another model dynamically var User = Waterline.Collection.extend({ identity: 'user', connection: 'default', attributes: { first_name: 'string', last_name: 'string' } }); orm.loadCollection(User); var defaults = config.defaults || {}; // This is where the magic happens var loader = new CollectionLoader(User, orm.connections, defaults); var collection = loader.initialize(orm); orm.collections[collection.identity.toLowerCase()] = collection; // Done! You can now use orm.collections.user :-D }); 

在v0.12中, sails.hooks.orm.normalizeModelDef不再存在。 另外, sails/lib/hooks/orm/loadUserModules转到了sails-hook-orm npm模块,不再是sails的一部分。

试试这个:“从指定的目录加载模型,控制器,服务,策略和configuration,并将它们注入到主要的Sails应用程序中。

https://github.com/leeroybrun/sails-util-mvcsloader