2016-10-08 5 views
3

Node.jsとSequelize(Postgresバックエンドを使用)を使用してウェブサイトを構築しています。私は、外部キーを持つ多くのオブジェクトを返すクエリがあり、私はビューに、外部キーが参照するオブジェクトのリストを渡したいと思います。Sequelizeクエリを同期して実行する

この例では、AttendancesにはHackathonキーが含まれています。ハカトンのリストを返したいとします。コードは非同期なので、当然の以下のものは、ノードでは動作しません:

models.Attendance.findAll({ 
    where: { 
     UserId: req.user.id 
    } 
}).then(function (data) { 
    var hacks = []; 
    for (var d in data) { 
     models.Hackathon.findOne({ 
      where: { 
       id: data[d].id 
      } 
     }).then(function (data1) { 
      hacks.append(data1); 
     }); 
    } 
    res.render('dashboard/index.ejs', {title: 'My Hackathons', user: req.user, hacks: hacks}); 
}); 

は、同期の方法でそのクエリを行うにはどのような方法がありますが、私は私が持っているそれまではビューを返さないことを意味しますすべてのオブジェクトでいっぱいの "ハッキング"リスト?

ありがとうございます!

+0

はあなたが滝と非同期モジュールを試してみましたか?それはあなたを助けることができます – abdulbarik

+0

ループで1つのレコードを見つけることはどちらの方法でもひどいデザインです。 1つのクエリでなければなりません。 –

答えて

3

Promise.allを使用してすべてのクエリを実行し、次の関数を呼び出します。あなたが車輪の再発明している

models.Attendance.findAll({ 
 
    where: { 
 
     UserId: req.user.id 
 
    } 
 
}).then(function (data) { 
 
    // get an array of the data keys, (not sure if you need to do this) 
 
    // it is unclear whether data is an object of users or an array. I assume 
 
    // it's an object as you used a `for in` loop 
 
    const keys = Object.keys(data) 
 
    // map the data keys to [Promise(query), Promise(query), {...}] 
 
    const hacks = keys.map((d) => { 
 
     return models.Hackathon.findOne({ 
 
     where: { 
 
      id: data[d].id 
 
     } 
 
     }) 
 
    }) 
 
    // user Promise.all to resolve all of the promises asynchronously 
 
    Promise.all(hacks) 
 
     // this will be called once all promises have resolved so 
 
     // you can modify your data. it will be an array of the returned values 
 
     .then((users) => { 
 
     const [user1, user2, {...}] = users 
 
     res.render('dashboard/index.ejs', { 
 
      title: 'My Hackathons', 
 
      user: req.user, 
 
      hacks: users 
 
     }); 
 
     }) 
 
});

1

、Sequelizeライブラリは、すでにこのすべてが考え抜かれています。あなたは、外貨キーが既に確立されていることを言いました。戦闘の半分以上が完了しました。

Hackathonsモデルを持ち込むためにwhereステートメント内に、すべての呼び出しを含めることができます。環境が正しく設定されていれば、これは機能します。図書館の下で物事を正しく設定する時間があれば、間違いを減らし、必要に応じて中断した場所から他の人に拾うことができます。これがどのくらいきれい

ルック...

models.Attendance.findAll({ 
    include: [{ 
     model: Hackathon, 
     as: 'hackathon' 
    }, 
    where: { 
     UserId: parseInt(req.user.id) // <---- like to parseInt to prevent SQL injection, but I believe Sequelize already covers this, can never be too safe ;-) 
    } 
}).then(function (data) { 
    // hackathon id 
    console.log(data.hackathon.id) 

    // attendance id 
    console.log(data.id) 
}) 

がSequelizeの詳細情報はここに含まれています: http://docs.sequelizejs.com/en/latest/docs/models-usage/

+0

あなたは文字通り安全すぎることがあります。あなたが "多分"のためにparseInt()呼び出しですべてをラッピングしているのであれば、あなたは貨物を扱っています。 – theraccoonbear

関連する問題