私は sequelize ORM を使用しています。すべてが素晴らしくてクリーンですが、クエリで使用するときに問題が発生しましたjoin
。ユーザーと投稿の 2 つのモデルがあります。
var User = db.seq.define('User',{
username: { type: db.Sequelize.STRING},
email: { type: db.Sequelize.STRING},
password: { type: db.Sequelize.STRING},
sex : { type: db.Sequelize.INTEGER},
day_birth: { type: db.Sequelize.INTEGER},
month_birth: { type: db.Sequelize.INTEGER},
year_birth: { type: db.Sequelize.INTEGER}
});
User.sync().success(function(){
console.log("table created")
}).error(function(error){
console.log(err);
})
var Post = db.seq.define("Post",{
body: { type: db.Sequelize.TEXT },
user_id: { type: db.Sequelize.INTEGER},
likes: { type: db.Sequelize.INTEGER, defaultValue: 0 },
});
Post.sync().success(function(){
console.log("table created")
}).error(function(error){
console.log(err);
})
投稿したユーザーの情報を含む投稿で応答するクエリが必要です。生のクエリでは、次のようになります。
db.seq.query('SELECT * FROM posts, users WHERE posts.user_id = users.id ').success(function(rows){
res.json(rows);
});
私の質問は、SQL クエリの代わりに ORM スタイルを使用するようにコードを変更するにはどうすればよいかということです。
ベストアンサー1
受け入れられた回答は技術的には間違っていませんが、元の質問にもコメント内のフォローアップの質問にも答えていません。私がここに来たのは、それを探していたからです。しかし、私はそれを理解したので、ここに述べます。
ユーザーを持つすべての投稿(ユーザーがいる投稿のみ)を検索する場合、SQL は次のようになります。
SELECT * FROM posts INNER JOIN users ON posts.user_id = users.id
これは意味的には OP の元の SQL と同じものです:
SELECT * FROM posts, users WHERE posts.user_id = users.id
あなたが望むのは次のようになります:
Posts.findAll({
include: [{
model: User,
required: true
}]
}).then(posts => {
/* ... */
});
required を true に設定することが、内部結合を生成するための鍵です。左外部結合 (リンクされたユーザーの有無に関係なく、すべての投稿を取得する) が必要な場合は、required を false に変更するか、デフォルトであるオフのままにします。
Posts.findAll({
include: [{
model: User,
// required: false
}]
}).then(posts => {
/* ... */
});
誕生年が 1984 年のユーザーの投稿をすべて検索する場合は、次のようにします。
Posts.findAll({
include: [{
model: User,
where: {year_birth: 1984}
}]
}).then(posts => {
/* ... */
});
where 句を追加するとすぐに、required がデフォルトで true になることに注意してください。
ユーザーが添付されているかどうかに関係なくすべての投稿を取得したいが、ユーザーが添付されている場合は 1984 年に生まれた投稿のみを取得する場合は、必要なフィールドを再度追加します。
Posts.findAll({
include: [{
model: User,
where: {year_birth: 1984}
required: false,
}]
}).then(posts => {
/* ... */
});
名前が「Sunshine」で、1984 年に生まれたユーザーに属するすべての投稿を取得するには、次のようにします。
Posts.findAll({
where: {name: "Sunshine"},
include: [{
model: User,
where: {year_birth: 1984}
}]
}).then(posts => {
/* ... */
});
名前が「Sunshine」であるすべての投稿が必要であり、投稿の post_year 属性と一致する同じ年に生まれたユーザーに属する投稿のみが必要な場合は、次のようにします。
Posts.findAll({
where: {name: "Sunshine"},
include: [{
model: User,
where: ["year_birth = post_year"]
}]
}).then(posts => {
/* ... */
});
誰かが自分の生まれた年を投稿するのは意味がないことはわかっていますが、これは単なる例なので、そのままにしておいてください。 :)
私はこれを(主に)このドキュメントから理解しました: