query using column from junction table - node.js

I have a Node entity with a many to many relationship with itself through Edge
var Node = db.define('nodes', {
'name': sequelize.STRING
});
var Edge = db.define('edges', {
'weight': sequelize.STRING
});
Node.hasMany(Node, { as: 'parents', foreignKey: 'parent_id', through: Edge});
Node.hasMany(Node, { as: 'children', foreignKey: 'child_id', through: Edge});
I want to get a nodes children which are created after a specific time using a query like the following
node.getChildren({
include: [Edge],
where: ['createdAt > ?', 1413000965754]
}).complete(function(err, children){
// ...
});
but I cant get it to work.

Related

How do I eager load multiple foreign keys including an or query from the same table, in Sequelize?

I'm searching for the captain.entry_date but I'm not able to create the query in a sequelize model.
My problem is that for any ship exists a captain but the ship_captain.captain_id sometimes is null.
For this cases the captain can be found about the route_id.
4 Tables :
ship, attributes:[id,name],
captain, attributes: [id, name, route_id, route_date]
ship_captain, attributes: [id, ship_id, route_id, captain_id]
route, attributes: [id, name]
select ship.name, c.name, c.entry_date
from ship left join ship_captain sc on ship.id = sc.ship_id
left join captain c on c.id = sc.captain_id or c.route_id = sc.route_id
What I've try so far is this but I can't give an OR operator into the last join
Ship.hasMany(ShipCaptain, {foreignKey: "ship_id"});
ShipCaptain.belongsTo(Ship, {foreignKey: "ship_id"});
Captain.hasMany(ShipCaptain, {as: "ship_captain_by_id", foreignKey: "captain_id"});
ShipCaptain.belongsTo(Captain, {as: "ship_captain_by_route", foreignKey: "captain_id"});
Captain.hasMany(ShipCaptain, {as: "ship_captain_by_route", foreignKey: "route_id"});
ShipCaptain.belongsTo(Captain, {as: "ship_captain_by_route", foreignKey: "route_id"});
const options = {
attributes: ["name"],
include: [
{
model: Captain,
as: 'ship_captain_per_id',
required: false,
attributes: ["name","route_date"],
},
{
model: Captain,
as: 'ship_captain_per_route',
required: false,
attributes: ["name","route_date"],
}
],
}
const elements = await Ship.findAll(options);
This is only an example code, may be that you want to rearrange the db attributes
but I tried to give my best to clarify the problem. I can't change the customers database.
If you really want to use only one association to get a captain by captain_id or route_id and not to use two associations and map them yourself then you need to define only one association hasOne (instead of hasMany) and always use the on option to join ShipCaptain with Captain by OR:
Ship.hasMany(ShipCaptain, {foreignKey: "ship_id"});
ShipCaptain.belongsTo(Ship, {foreignKey: "ship_id"});
ShipCaptain.belongsTo(Captain, {as: "captain_by_captain", foreignKey: "captain_id"});
...
const options = {
attributes: ["name"],
include: [
{
model: ShipCaptain,
required: false,
include: [{
model: Captain,
required: false,
as: 'captain_by_captain',
attributes: ["name","route_date"],
on: {
[Op.or]: [{
id: Sequelize.col('ship_captain.captain_id'
}, {
id: Sequelize.col('ship_captain.route_id'
}]
}
}
]
},
],
}
const elements = await Ship.findAll(options);

many to many association in node js

here is link of my code . I am getting error in index.js in api-routes-index.js. getting error undefined map function
I guess here you have an error:
subcategories: products.subcategories.map(Subcategory => {
products is array, you can't get subcategories from array. Change it to this code:
subcategories: Product.subcategories.map(Subcategory => {
Many to many associations in sequilize.js
This will be helpful for you to solve the issue:
One product has many order
One order has many product
As a result of many to many we have junction table "orderproduct" which contains product_id and order_id.
// In product model
product.belongsToMany(order, {
through: 'orderproduct',
foreignKey: 'product_id'
});
// In order model
order.belongsToMany(product, {
through: 'orderproduct',
foreignKey: 'order_id'
});
// In oderproduct model
orderproduct.belongsTo(product, {
foreignKey: { name: 'product_id', allowNull: false }
});
orderproduct.belongsTo (order, {
foreignKey: { name: 'order_id', allowNull: false }
});
}

Sequelize: Joining Many to Many tag table with another table in postgresql

I am trying to setup many to many relationship in Sequelize for my Postgres tables using a tag (lookup) table. I was successful in setting up the relationship.
Now my lookup table, has an additional field which is a foreign key to another table. I want the data for that table to be included in my result set. This is where I am having hard time figuring out the syntax.
My models:
Models.user = sequelize.define('user', { //attributes});
Models.school = sequelize.define('school', { //attributes });
Models.role = sequelize.define('role', { //attributes });
Models.userSchools = sequelize.define('user_school', {
user_school_id: { type: Sequelize.INTEGER, primaryKey: true }
});
Models.user.belongsToMany(Models.school, { through: Models.userSchools, foreignKey: 'user_id', otherKey: 'school_id' });
Models.school.belongsToMany(Models.user, { through: Models.userSchools, foreignKey: 'school_id', otherKey: 'user_id' });
Models.userSchools.belongsTo(Models.role, { foreignKey: 'role_id' });
Working query: This query gives me all the users and their schools.
Models.user.findAll({
where: {
//condition
},
include: [Models.school]
})
Now I want to include the role for each schools. None of the below queries are working.
Models.user.findAll({
where: {
//conditions
},
include: [Models.schools, Models.role]
})
Above query is throwing an error saying role is not associated to user, which is expected.
Models.user.findAll({
where: {
//conditions
},
include: [Models.schools, {model: Models.userSchools, include: Models.role}]
})
This query is also throwing an error:
"userSchools is not associated to user".
Can any one help with syntax to how I can get the role information from the userSchools model?
Edit:
I have add a "through" condition which gets me the role_id but not the related role data.
Models.user.findAll({
where: {
//conditions
},
include: [{
model: Models.school,
as: 'schools',
through: {
attributes: ['role_id']
}
}]
})

get associations with belongsToMany in sequelize.js

I have a many-to-many relation between User and Device model, through a UserDevice join table:
device.belongsToMany(user, {
through: {
model: userDevice
},
foreignKey: "deviceId",
as: "customers"
});
user.belongsToMany(device, {
through: {
model: userDevice
},
foreignKey: "customerId",
as: "devices"
});
setCustomers: Sequelize.BelongsToManySetAssociationsMixin<UserInstance, string, UserDeviceAttribute>;
getCustomers: Sequelize.BelongsToManyGetAssociationsMixin<UserInstance>;
I can find devices and populate customers correctly with:
this.db.models.Device.findAll({
include: [{
model: User,
as: "customers"
}]
I can't figure out how I can populate customers in other scenarios, i.e. when I'm setting customers manually. Right now I'm trying something like:
return device.setCustomers(customers)
.then(() => {
return device.getCustomers();
})
.then((users) => {
device.setAttributes("customers", users);
return device;
});
but it's not working, setAttributes doesn't set customers field.
The answer is in the question. I found the bug today when encountered same issue.
https://github.com/sequelize/sequelize/blob/master/lib/model.js#L3483
setAttributes seems to be a reserved method for sequelize.

How can I make an order with n:m associations?

I'm using sequelize.js for ORM, and I have some questions while I use it.
Models looks like this
var Keyword = db.define('keyword', {
name: db.STRING,
});
var KeywordSearchableMap = db.define('keyword_searchable_map', {
keyword_id: db.INTEGER,
searchable: db.STRING,
searchable_id: db.STRING,
score: db.STRING,
});
var Searchable = db.define('searchable') {
name: db.STRING,
});
Keyword.belongsToMany(Searchable, {
through: {
model: KeywordSearchableMap,
},
foreignKey: 'keyword_id'
});
Searchable.belongsToMany(Keyword, {
through: {
model: KeywordSearchableMap,
},
foreignKey: 'searchable_id'
});
And I want to get 'Searchable' things by Keyword.getSearchables() order by 'score' field in 'KeywordSearchableMap'
Is there any methods to get sorted searchable objects?

Resources