2013-06-24 79 views
-1

我對貓鼬模型定義如下:呼叫需要在貓鼬模型不止一次

user.js的

module.exports = function() { 
    var mongoose = require('mongoose'); 

    // Creates a new Mongoose Schema object 
    var Schema = mongoose.Schema; 

    // Collection to hold users 
    var UserSchema = new Schema({ 
     username: { type: String, required: true }, 
     password: { type: String, required: true }, 
    },{ 
     versionKey: false 
    } 
); 

    // Creates the Model for the User Schema 
    var User = mongoose.model('User', UserSchema); 

    var getUserById = function(id, callback) { 
    User.findById(id, callback); 
    } 

    var getUserByUsername = function(username, callback) { 
    var query = {username: username}; 
    User.findOne(query, callback); 
    } 


    return { 
    getUserById: getUserById, 
    getUserByUsername: getUserByUsername 
    } 
}() 

基本上我返回一個公共的接口,用戶模型的客戶端可以使用。 I.E.我的路線爲用戶抓住模型,並且可以調用定義的兩個公共方法,而不是其他方法。我這樣做是爲了從我的路線中抽象出我正在使用的mongodb/mongoose這一事實。我很可能會有一個用戶模型與postgres進行對話,也可能只是切換到postgres。因此,我不希望通過代碼尋找路線方法中稱爲貓鼬特定功能的地方。

這是我的問題。大多數無處不在的代碼時,我需要一個模塊我稱之爲

var someUtil = require('./someUtil'); 

但是,如果我這樣做一次以上的貓鼬模型我得到一個錯誤,指出它不能被定義兩次。

var User = require('./user'); // Cannot put this in more than one file without getting an error. 

有沒有更好的方式來編碼user.js的文件,這樣我可以提供一個公共接口,以我的用戶模型,但只定義的模式一度讓我可以調用需要一個以上的時間在該文件?

+2

AFAIK節點緩存需要模塊的結果,因此上述函數不應該運行兩次。除此之外,沒有理由將代碼封裝在自執行函數中,只需公開方法,如'exports.getUserById = getUserById; // etc'。 –

回答

0

我也遇到過這個問題。

有些事情,你可以做的是包裹在一個嘗試捕捉

模式定義替換爲這一行var User = mongoose.model('User', UserSchema);

var User; 
try { 
    User = mongoose.model('User', UserSchema); 
} 
catch(e) { 
    User = mongoose.model('User'); 
} 

不知道它的最好的方式,但它會奏效。

0

安德烈亞斯是正確的:

AFAIK node caches the result of requireing a module, and thus the above function should not be run twice. Other than that there's no reason to wrap you code in a self-executing function, just expose the methods like exports.getUserById = getUserById; //etc. 
3

你應該貓鼬模型從你把它包裝服務分開。

我建議你有一個模型文件夾,每個模式1個文件,每個文件看起來有點像這樣:

'use strict'; 

var mongoose = require('mongoose'), 
    Schema = mongoose.Schema 

var User = new Schema({ 
    ...fields your schema will have 
}) 

//additional virtuals or configuration 

module.exports = mongoose.model('User', User) 

然後有一個UserService一個services文件夾,需要這種模式:

var User = require('../models/User') 

function UserService(){ 
    //create User, delete User, etc. 
} 

module.exports = new UserService() 

那麼從現在開始在你的控制器或路由中只需要UserService。你不會有這樣的問題,你的代碼組織得更好。

0

我遇到了這個問題,我想我會提供我的答案。我的問題稍微複雜一些,因爲我的模式中有'ref'定義。我還沒有深入到「爲什麼」的底部,但基本上發生了什麼是依賴鏈導致節點需要兩次相同的文件。這是驗證,因爲我得到console.log輸出兩次。我之前的做法是簡單地導出模式,而不是模型,但是這樣做很煩人,因爲我必須在執行開始時引導所有模型。經過一番修改之後,我決定採用這種模式(使用coffeescript):

Mongoose = require 'mongoose' 

unless 'Foo' in Mongoose.modelNames() 
    schema = new Mongoose.Schema 
    bar: String 
    Mongoose.model 'Foo', schema 

module.exports = Mongoose.model 'Foo'