Given the following models :
sequelize.define('Tag', {
id : {
type : INTEGER,
allowNull : false,
primaryKey : true,
autoIncrement : true
},
slug : {
type : STRING(40),
allowNull : false
},
moderated : {
type : BOOLEAN,
allowNull : false,
defaultValue : false
},
moderatedBy : {
type : INTEGER,
defaultValue : null,
field : 'moderated_by'
},
moderatedDate : {
type : DATE,
defaultValue : null,
field : 'moderated_date'
}
}, {
tableName : 'tag',
classMethods : {
associate : (models) => {
model.belongsToMany(models.TagType, {
as : 'types',
through : models.TagHasTagType,
foreignKey : 'tag_id',
otherKey : 'tag_type_id'
})
/**
* To get the TagTranslation objects for this tag :
*
* tagInstance.getTranslations()
*/
model.hasMany(models.TagTranslation, {
as : 'translations',
foreignKey : 'tag_id'
})
}
}
})
sequelize.define('Language', {
id : {
type : INTEGER,
allowNull : false,
primaryKey : true,
autoIncrement : true
},
fullname : {
type : STRING(20),
allowNull : false
},
// isoCode for ISO 639-1 language code
isoCode : {
type : STRING(2),
allowNull : false,
field : 'iso_639_1'
},
daletLocale : {
type : STRING(2),
allowNull : false,
field : 'dalet_locale'
},
isRTL : {
type : BOOLEAN,
defaultValue : false,
field : 'is_rtl'
},
live : {
type : BOOLEAN,
defaultValue : false
},
websiteSubdomain : {
type : STRING(20),
defaultValue : null,
field : 'website_subdomain'
},
collateLocale : {
type : STRING(10),
allowNull : false,
field : 'collate_locale'
},
priority : {
type : INTEGER,
defaultValue : 1
}
}, {
tableName : 'lang'
})
sequelize.define('TagTranslation', {
tagId : {
type : INTEGER,
allowNull : false,
primaryKey : true,
references : {
model : 'tag',
key : 'id'
},
field : 'tag_id'
},
langId : {
type : INTEGER,
allowNull : false,
primaryKey : true,
references : {
model : 'lang',
key : 'id'
},
field : 'lang_id'
},
slug : {
type : STRING(40),
allowNull : false
},
title : {
type : STRING(80),
allowNull : false
},
hotTopic : {
type : BOOLEAN,
allowNull : false,
defaultValue : false,
field : 'hot_topic'
},
hotTopicStartDate : {
type : DATE,
defaultValue : null,
field : 'hot_topic_start_date'
},
hotTopicEndDate : {
type : DATE,
defaultValue : null,
field : 'hot_topic_end_date'
}
}, {
tableName : 'tag_translation',
classMethods : {
associate : (models) => {
model.belongsTo(models.Language, {
as : 'language',
foreignKey : 'lang_id'
})
}
}
})
I want to be able to retrieve all the tags that have a translation with a given slug in a given language. Example : tags with slug like 'cam%' and language = 'english'
For that, I use the following code :
function getTagsBySlugAndLanguage({ slug, language }) {
const options = {
limit : 100,
offset : 0
}
const include = [{
as : 'translations',
model : TagTranslation,
where : {
slug : {
like : slug
}
},
include : [{
as : 'language',
model : Language,
where : {
fullname : {
like : language
}
}
}]
}]
return Tag.findAndCountAll(
Object.assign({}, options, { include })
)
}
It generates me two different queries (one for the count, and one for the actual fetch).
Count query :
SELECT count(`Tag`.`id`) AS `count`
FROM `tag` AS `Tag`
INNER JOIN `tag_translation` AS `translations`
ON `Tag`.`id` = `translations`.`tag_id`
AND `translations`.`slug` LIKE 'cam%'
INNER JOIN `lang` AS `translations.language`
ON `translations`.`lang_id` = `translations.language`.`id`
AND `translations.language`.`fullname` LIKE '%en%';
Fetch query :
SELECT `Tag`.*,
`translations`.`tag_id` AS `translations.tagId`,
`translations`.`lang_id` AS `translations.langId`,
`translations`.`slug` AS `translations.slug`,
`translations`.`title` AS `translations.title`,
`translations`.`hot_topic` AS `translations.hotTopic`,
`translations`.`hot_topic_start_date` AS `translations.hotTopicStartDate`,
`translations`.`hot_topic_end_date` AS `translations.hotTopicEndDate`,
`translations`.`lang_id` AS `translations.lang_id`,
`translations`.`tag_id` AS `translations.tag_id`
FROM
(SELECT `Tag`.`id`,
`Tag`.`slug`,
`Tag`.`moderated`,
`Tag`.`moderated_by` AS `moderatedBy`,
`Tag`.`moderated_date` AS `moderatedDate`,
`translations.language`.`id` AS `translations.language.id`,
`translations.language`.`fullname` AS `translations.language.fullname`,
`translations.language`.`iso_639_1` AS `translations.language.isoCode`,
`translations.language`.`dalet_locale` AS `translations.language.daletLocale`,
`translations.language`.`is_rtl` AS `translations.language.isRTL`,
`translations.language`.`live` AS `translations.language.live`,
`translations.language`.`website_subdomain` AS `translations.language.websiteSubdomain`,
`translations.language`.`collate_locale` AS `translations.language.collateLocale`,
`translations.language`.`priority` AS `translations.language.priority`
FROM `tag` AS `Tag`
INNER JOIN `lang` AS `translations.language`
ON `translations`.`lang_id` = `translations.language`.`id`
AND `translations.language`.`fullname` LIKE '%en%'
WHERE
(SELECT `tag_id`
FROM `tag_translation` AS `TagTranslation`
WHERE (`TagTranslation`.`tag_id` = `Tag`.`id`
AND `TagTranslation`.`slug` LIKE 'cam%') LIMIT 1 ) IS NOT NULL LIMIT 0, 100) AS `Tag`
INNER JOIN `tag_translation` AS `translations`
ON `Tag`.`id` = `translations`.`tag_id`
AND `translations`.`slug` LIKE 'cam%';
The fetch query results in the following:
SequelizeBaseError: ER_BAD_FIELD_ERROR: Unknown column 'translations.lang_id' in 'on clause'
It seems to be a bug with Sequelize, and I have no idea how I can get around this :(
Is there a better way to perform this?
Versions:
Dialect: mysql Database version: 5.6.35 Sequelize version: 3.30.2
via Shahor
No comments:
Post a Comment