How can i access junction table in Sequelize? - node.js

Good evenings,fine sirs. I am working with Sequelize with NodeJS. I created Many-to-many association between two table User and Project.
//This is Project Model
const { Model } = require("sequelize");
module.exports = (sequelize, DataTypes) => {
class Project extends Model {
static associate(models) {
const { User, Issue } = models;
this.belongsToMany(User, {
as: "project_users",
foreignKey: "project_id",
through: "projectuser",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
this.hasMany(Issue, {
as: "project_issues",
foreignKey: "project_id",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
}
}
Project.init(
{
project_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
projectname: {
type: DataTypes.STRING,
allowNull: false,
},
description: {
type: DataTypes.STRING,
},
projecturl: {
type: DataTypes.STRING,
},
},
{
sequelize,
modelName: "Project",
}
);
return Project;
};
//This is User Model
const { Model } = require("sequelize");
module.exports = (sequelize, DataTypes) => {
class User extends Model {
static associate(models) {
const { Commet, Project, Issue } = models;
this.hasMany(Commet, {
foreignKey: "user_id",
as: "user_commets",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
this.belongsToMany(Project, {
as: "project_user",
foreignKey: "user_id",
through: "projectuser",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
this.belongsToMany(Issue, {
as: "user_issues",
foreignKey: "user_id",
through: "issueuser",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
}
}
User.init(
{
user_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
role: {
type: DataTypes.STRING,
allowNull: false,
validate: {
roleValidator(role) {
let rolet = role.toLowerCase();
if (roles[rolet] === undefined) {
throw new Error("Invalid Role");
}
},
},
},
username: { type: DataTypes.STRING, allowNull: false },
usersurname: { type: DataTypes.STRING, allowNull: false },
avatarURL: { type: DataTypes.STRING, allowNull: true },
password: {
type: DataTypes.STRING,
validate: {
passwordValidator(password) {
if (password.length <= 5) {
throw new Error("Cannot be less than 5 characters");
}
},
},
},
email: {
type: DataTypes.STRING,
unique: true,
validate: { isEmail: true },
},
},
{
sequelize,
modelName: "User",
}
);
return User;
};
My question may be silly but, do i need to create junction table manually to access it from my code or is there any way to access it without creating it? Thank you for your answers.

Related

Sequelize: build a staggered triple association

I'm trying to make a save that corresponds to three models: Person ->(hasOne)-> ContactInfo ->(hasMany)-> Phone.
Models:
Person:
'use strict';
const chalk = require('chalk');
const { Model } = require('sequelize');
const { gender } = require("../utils/enumList");
const { ageCalculation } = require('../utils/extraFunctions');
module.exports = (sequelize, DataTypes) =>
{
class Person extends Model
{
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models)
{
//Has one
Person.hasOne(models.ContactInfo, {
as: 'contactInfo_R',
foreignKey: {
name: "personId",
allowNull: false,
type: DataTypes.UUID,
unique: true,
},
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
Person.hasOne(models.Holder, {
as: 'holder_R',
foreignKey: {
name: "personId",
type: DataTypes.UUID,
allowNull: false,
unique: true,
},
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
Person.hasOne(models.Intermediary, {
as: 'intermediary_R',
foreignKey: {
name: "personId",
allowNull: false,
type: DataTypes.UUID,
unique: true,
},
onDelete: "CASCADE",
onUpdate: "CASCADE"
});
//Has many
Person.hasMany(models.Insured, {
as: "insured_R",
foreignKey: {
name: "personId",
allowNull: false,
type: DataTypes.UUID,
unique: false,
},
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
}
}
Person.init({
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV1,
primaryKey: true,
},
names: {
type: DataTypes.STRING,
allowNull: false,
},
surnames: {
type: DataTypes.STRING,
allowNull: false,
},
birth_date: {
type: DataTypes.DATEONLY,
allowNull: false,
},
age: {
type: DataTypes.VIRTUAL,
get()
{
return ageCalculation(this.getDataValue("birth_date"));
},
set(value)
{
throw new Error("No es necesario introducir la edad de la persona");
}
},
gender: {
type: DataTypes.ENUM(gender),
allowNull: false,
},
dni: {
type: DataTypes.STRING,
allowNull: true,
},
support_dni_address: {
type: DataTypes.STRING,
allowNull: true,
}
}, {
sequelize,
modelName: 'Person',
});
return Person;
};
ContactInfo:
'use strict';
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) =>
{
class ContactInfo extends Model
{
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models)
{
// define association here
//Has many
ContactInfo.hasMany(models.Phone, {
as: "phone_R",
foreignKey: {
name: "contactInfoId",
type: DataTypes.UUID,
allowNull: false,
},
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
//Belong to
ContactInfo.belongsTo(models.Person, {
as: "person_R",
foreignKey: {
name: "personId",
type: DataTypes.UUID,
allowNull: false,
unique: true,
},
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
}
}
ContactInfo.init({
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV1,
primaryKey: true,
},
nation: {
type: DataTypes.STRING,
allowNull: false,
},
region: {
type: DataTypes.STRING,
allowNull: true,
},
city: {
type: DataTypes.STRING,
allowNull: true
},
address_1: {
type: DataTypes.STRING,
allowNull: true,
},
address_2: {
type: DataTypes.STRING,
allowNull: true,
},
email: {
type: DataTypes.STRING,
allowNull: false,
validate: {
isEmail: {
arg: true,
msg: "Por favor, usar un formato de correo electrónico valido"
},
},
},
}, {
sequelize,
modelName: 'ContactInfo',
});
return ContactInfo;
};
Phone:
'use strict';
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) =>
{
class Phone extends Model
{
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models)
{
//Belong to
Phone.contactInfo = Phone.belongsTo(models.ContactInfo, {
as: "contactInfo_R",
foreignKey: {
name: "contactInfoId",
allowNull: false,
type: DataTypes.UUID,
unique: false
},
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
}
}
Phone.init({
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV1,
primaryKey: true,
},
nation_phone_code: {
type: DataTypes.STRING,
allowNull: false,
//TODO add predefined list
},
phone_number: {
type: DataTypes.STRING,
allowNull: false,
//TODO add formatting and validating
}
}, {
sequelize,
modelName: 'Phone',
});
return Phone;
};
Build Code:
let HolderPerson = await Models.Person.build({
names: personHolder_form.names,
surnames: personHolder_form.surnames,
birth_date: personHolder_form.birth_date,
gender: personHolder_form.gender,
dni: personHolder_form.dni,
support_dni_address: personHolder_form.support_dni_address,
contactInfo_R: {
nation: ContactInfoHolder_form.nation,
region: ContactInfoHolder_form.region,
city: ContactInfoHolder_form.city,
address_1: ContactInfoHolder_form.address_1,
address_2: ContactInfoHolder_form.address_2,
email: ContactInfoHolder_form.email,
phone_R: [
{ phone_number: '04269872654', nation_phone_code: '+58' },
{ phone_number: '02569871452', nation_phone_code: '+57' }
],
}
}, {
include: [{
association: {
model: Models.ContactInfo,
as: 'contactInfo_R'
},
include: [{
model: Models.Phone,
as: 'phone_R'
}]
}],
});
console.log(HolderPerson);
Console Error:
TypeError: Cannot read property 'name' of undefined
at Function._conformInclude (/home/sistemas/proyectos/Sistema_PreCris/node_modules/sequelize/lib/model.js:301:50)
at /home/sistemas/proyectos/Sistema_PreCris/node_modules/sequelize/lib/model.js:270:61
at Array.map (<anonymous>)
at Function._conformIncludes (/home/sistemas/proyectos/Sistema_PreCris/node_modules/sequelize/lib/model.js:270:39)
at new Model (/home/sistemas/proyectos/Sistema_PreCris/node_modules/sequelize/lib/model.js:104:24)
at new Person (/home/sistemas/proyectos/Sistema_PreCris/src/models/Person.js:10:5)
at Function.build (/home/sistemas/proyectos/Sistema_PreCris/node_modules/sequelize/lib/model.js:1326:12)
at primeraParte (/home/sistemas/proyectos/Sistema_PreCris/src/controllers/pruebas.js:86:52)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
I've done what I understand from the sequelize documentation but I can't get it to work. If I remove the association from the third model it works. I do not know what else to do.

Sequelize Cannot Access "projectuser" before initialization

sirs. I have 2 models in sequelize ,Project and User. Relationship between this two models is many-to-many. Fot this relation, I have created projectuser. But when i trying to insert intoprojectuser console gives me ReferenceError: Cannot access 'projectuser' before initialization error. [NodeJs][Sequelize] ReferenceError: Cannot access 'ModelName' before initialization I have tried this solution but i think it is too complex solution. Can you please help me?
const { Model } = require("sequelize");
module.exports = (sequelize, DataTypes) => {
class Project extends Model {
static associate(models) {
const { User, Issue, projectuser } = models;
this.belongsToMany(User, {
as: "project_users",
foreignKey: "project_id",
through: "projectuser",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
this.hasMany(Issue, {
as: "project_issues",
foreignKey: "project_id",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
}
}
Project.init(
{
project_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
projectname: {
type: DataTypes.STRING,
allowNull: false,
},
description: {
type: DataTypes.TEXT,
},
projecturl: {
type: DataTypes.STRING,
},
},
{
sequelize,
modelName: "Project",
}
);
return Project;
};
const { Model } = require("sequelize");
module.exports = (sequelize, DataTypes) => {
class User extends Model {
static associate(models) {
const { Commet, Project, Issue, projectuser, issueuser } = models;
this.hasMany(Commet, {
foreignKey: "user_id",
as: "user_commets",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
this.belongsToMany(Project, {
as: "project_user",
foreignKey: "user_id",
through: "projectuser",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
this.belongsToMany(Issue, {
as: "user_issues",
foreignKey: "user_id",
through: issueuser,
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
}
}
User.init(
{
user_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
role: {
type: DataTypes.STRING,
allowNull: false,
validate: {
roleValidator(role) {
let rolet = role.toLowerCase();
if (roles[rolet] === undefined) {
throw new Error("Invalid Role");
}
},
},
},
username: { type: DataTypes.STRING, allowNull: false },
usersurname: { type: DataTypes.STRING, allowNull: false },
avatarURL: { type: DataTypes.STRING, allowNull: true },
password: {
type: DataTypes.STRING,
validate: {
passwordValidator(password) {
if (password.length <= 5) {
throw new Error("Cannot be less than 5 characters");
}
},
},
},
email: {
type: DataTypes.STRING,
unique: true,
validate: { isEmail: true },
},
},
{
sequelize,
modelName: "User",
}
);
return User;
};
const {
Model
} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class projectuser extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
// define association here
}
}
projectuser.init({
deneme: DataTypes.STRING
}, {
sequelize,
modelName: 'projectuser',
});
return projectuser;
};

postgres returns another table column while inserting data in sequelize

When I try to insert new category, I got this error:
error: column "image" does not exist
sql: 'INSERT INTO "Categories" ("id","createdAt","updatedAt") VALUES (DEFAULT,$1,$2) RETURNING "id","image","title","createdAt","updatedAt";'
The problem is that it doesn't insert name and other values and returns columns belong to post table.
My guesses are the problem of sequelize-cli and sequelize version or missing something in models or migrations.
I only insert values into name, createdAt and updatedAt column:
await Category.create({
name: req.body.name,
createdAt: new Date(),
updatedAt: new Date()
});
My category model:
const { Model } = require("sequelize");
module.exports = (sequelize, DataTypes) => {
class Category extends Model {
static associate(models) {
Category.hasMany(models.Post, { as: "posts", foreignKey: "categoryId" });
}
}
Category.init(
{
name: DataTypes.STRING
},
{
sequelize,
modelName: "Category"
}
);
return Category;
};
My Post Model:
const { Model } = require("sequelize");
module.exports = (sequelize, DataTypes) => {
class Post extends Model {
static associate(models) {
Post.belongsTo(models.Category, { foreignKey: "categoryId", onDelete: "CASCADE", as: "category" });
}
}
Post.init(
{
title: DataTypes.STRING,
image: DataTypes.STRING,
content: DataTypes.TEXT,
categoryId: DataTypes.INTEGER
},
{
sequelize,
modelName: "Post"
}
);
return Post;
};
Post migration:
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable("Posts", {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
title: {
type: Sequelize.STRING
},
image: {
type: Sequelize.STRING
},
content: {
type: Sequelize.TEXT
},
categoryId: {
type: Sequelize.INTEGER,
allowNull: false,
onDelete: "CASCADE",
references: {
model: "Categories",
key: "id"
}
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
Category migration:
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable("Categories", {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
name: {
type: Sequelize.STRING
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
});
},
I couldn't find solution for this, therefor I used sequelize.query

Sequelize Node Js Seeder file with Many-to-Many Association

I would like to find out what is the right way to add a many-to-many relation when seeding records with sequelize-cli. Now I understand that the easiest way to do this is to create another seeder file and manually set the values but is there a way to make some changes to my 2_user seeder file so that when a user is seeded with some value given for the role it automatically makes a record in the user_roles table. So basically same as the user.setRoles() one can use but in the seeder files. Any help is much appreciated.
Models
user.model.js
'use strict';
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class User extends Model {
static associate(models) {
User.belongsToMany(models.Role, {
through: 'user_roles',
foreignKey: 'user_id',
otherKey: 'role_id',
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
});
User.hasMany(models.User_Role);
User.hasMany(models.Address, {
foreignKey: 'user_id',
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
});
}
}
User.init(
{
user_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
email: DataTypes.STRING,
password: DataTypes.STRING,
bio: DataTypes.STRING,
activity_status: DataTypes.BOOLEAN,
},
{
sequelize,
modelName: 'User',
}
);
return User;
};
role.model.js
'use strict';
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class User extends Model {
static associate(models) {
User.belongsToMany(models.Role, {
through: 'user_roles',
foreignKey: 'user_id',
otherKey: 'role_id',
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
});
User.hasMany(models.User_Role);
User.hasMany(models.Address, {
foreignKey: 'user_id',
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
});
}
}
User.init(
{
user_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
email: DataTypes.STRING,
password: DataTypes.STRING,
bio: DataTypes.STRING,
activity_status: DataTypes.BOOLEAN,
},
{
sequelize,
modelName: 'User',
}
);
return User;
};
user_role.model
'use strict';
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class User_Role extends Model {
static associate(models) {
User_Role.belongsTo(models.User, {
foreignKey: 'user_id',
});
User_Role.belongsTo(models.Role, {
foreignKey: 'role_id',
});
}
}
User_Role.init(
{
user_role_id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
},
{
sequelize,
modelName: 'User_Role',
}
);
return User_Role;
};
Migrations
1-create-user
'use strict';
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable('users', {
user_id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
},
email: {
type: Sequelize.STRING,
unique: true,
},
password: {
type: Sequelize.STRING,
},
bio: {
type: Sequelize.STRING,
},
activity_status: {
type: Sequelize.BOOLEAN,
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
},
});
},
async down(queryInterface, Sequelize) {
await queryInterface.dropTable('users');
},
};
3-create-role
'use strict';
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable('roles', {
role_id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
unique: true,
type: Sequelize.INTEGER,
},
user_type: {
type: Sequelize.STRING,
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
},
});
},
async down(queryInterface, Sequelize) {
await queryInterface.dropTable('roles');
},
};
6-create-user_role
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.createTable('user_roles', {
user_role_id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
},
user_id: {
type: Sequelize.INTEGER,
references: { model: 'users', key: 'user_id' },
onDelete: 'CASCADE',
},
role_id: {
type: Sequelize.INTEGER,
references: { model: 'roles', key: 'role_id' },
onDelete: 'CASCADE',
},
createdAt: {
allowNull: false,
type: Sequelize.DATE,
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE,
},
});
},
async down(queryInterface, Sequelize) {
await queryInterface.dropTable('user_roles');
},
};
Seeders
1_role
'use strict';
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.bulkInsert(
'roles',
[
{
user_type: 'courier',
createdAt: new Date(),
updatedAt: new Date(),
},
{
user_type: 'receiver',
createdAt: new Date(),
updatedAt: new Date(),
},
{
user_type: 'donor',
createdAt: new Date(),
updatedAt: new Date(),
},
{
user_type: 'admin',
createdAt: new Date(),
updatedAt: new Date(),
},
],
{}
);
},
async down(queryInterface, Sequelize) {
await queryInterface.bulkDelete('Roles', null, {});
},
};
2_user
('use strict');
var bcrypt = require('bcryptjs');
module.exports = {
async up(queryInterface, Sequelize) {
await queryInterface.bulkInsert(
'users',
[
{
email: 'courier#email.com',
password: bcrypt.hashSync('PassWord123#', 10),
bio: 'This is a courier type user!',
activity_status: true,
createdAt: new Date(),
updatedAt: new Date(),
role_id: 1,
},
{
email: 'donor#email.com',
password: bcrypt.hashSync('PassWord123#', 10),
bio: 'This is a donor type user!',
activity_status: true,
createdAt: new Date(),
updatedAt: new Date(),
},
{
email: 'receiver#email.com',
password: bcrypt.hashSync('PassWord123#', 10),
bio: 'This is a Receiver type user!',
activity_status: true,
createdAt: new Date(),
updatedAt: new Date(),
},
{
email: 'admin#email.com',
password: bcrypt.hashSync('PassWord123#', 10),
bio: 'This is a Admin type user!',
activity_status: true,
createdAt: new Date(),
updatedAt: new Date(),
},
],
{}
);
},
async down(queryInterface, Sequelize) {
await queryInterface.bulkDelete('Users', null, {});
},
};

Sequelizejs is not associated to

I made some associate but it did not work, probably with me that something is wrong, ask for help.
There are two models
module.exports = function (sequelize, DataTypes) {
var pages_lang = require('./pages_lang')(sequelize, DataTypes);
return sequelize.define('pages', {
id: {
type: DataTypes.INTEGER(10),
allowNull: false,
primaryKey: true,
autoIncrement: true,
references : { model: "pages_lang", key: "page_id" }
},
name: {
type: DataTypes.STRING,
allowNull: false
},
published: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: '0'
},
createdAt: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: '0000-00-00 00:00:00'
},
updatedAt: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: '0000-00-00 00:00:00'
}
}, {
classMethods: {
associate: function (models) {
this.hasMany(models.pages_lang, {onDelete: 'SET NULL', onUpdate: 'CASCADE', foreignKey: 'page_id', as: 'pages', through: models.pages_lang});
},
getAll() {
return this.findAll({include: [{model: pages_lang, as: 'pages_lang'}]}).then(function (result) {
return result;
});
}
}
});
};
module.exports = function (sequelize, DataTypes) {
return sequelize.define('pages_lang', {
id: {
type: DataTypes.INTEGER(10),
allowNull: false,
primaryKey: true,
autoIncrement: true
},
page_id: {
type: DataTypes.INTEGER(10),
allowNull: false,
references : { model: "pages", key: "id" }
},
content: {
type: DataTypes.TEXT,
allowNull: false
}
}, {
classMethods: {
associate: function (models) {
this.belongsTo(models.pages, {foreignKey: 'id', foreignKeyConstraint:true, as: 'pages', through: models.pages});
}
}
});
};
But when you call results in an error
Unhandled rejection Error: pages_lang (pages_lang) is not associated
to pages!
Advance very grateful for the help
Your association alias (as) should match what you pass to findAll
this.hasMany(models.pages_lang, {onDelete: 'SET NULL', onUpdate: 'CASCADE', foreignKey: 'page_id', as: 'pages_lang' });
return this.findAll({include: [{model: pages_lang, as: 'pages_lang'}]});
Since the model is already called pages_lang, you can also skip the alias completely:
this.hasMany(models.pages_lang, {onDelete: 'SET NULL', onUpdate: 'CASCADE', foreignKey: 'page_id'});
return this.findAll({include: [pages_lang]});
Notice that I removed the through argument - it should only be used for belongsToMany (many-to-many)

Resources