这篇文章有3个更新,可能很长。请参阅原始帖子部分。
Annonce
代码请注意,这是我目前的代码。我更新了url()
方法并对afterCreate()
内的所有内容进行了评论。但代码仍然相同。 (对不起,它只是复制粘贴,所以评论都是法语)。
/**
* Annonce.js
*
* @description :: TODO: You might write a short summary of how this model works and what it represents here.
* @docs :: http://sailsjs.org/#!documentation/models
*/
module.exports = {
tableName: 'annonce',
autoPK: true,
attributes: {
qte_commande: {
type: 'integer',
defaultsTo: 1,
required: true
},
date_mise_en_ligne: 'date',
taille_echantillon: {
type: 'string',
enum: ['P', 'M', 'G'] // TODO : entité
},
qte_echantillons_ini: {
type: 'integer',
required: true,
defaultsTo: 1
},
qte_echantillons: {
type: 'integer'
},
titre_annonce: {
type: 'text',
required: true
},
texte_annonce_md: {
type: 'text',
required: true
},
slug: {
type: 'string',
unique: true
},
prix: {
type: 'float',
required: true
},
/*
* Associations
*/
utilisateur: {
model: 'utilisateur'
},
variete: {
model: 'variete'
},
echantillons: {
collection: 'echantillon',
via: 'annonce'
},
/*
* Méthode d'instance
*/
url: function(bool_url_courte) {
// Si la variété n'est pas accessible, on ne peut pas connaître son URL.
// Dans ce cas il y a un problème, mais on peut toujours donner l'url courte.
if (!this.variete) {
sails.log.warn(new Error('Variété non accessible depuis Annonce.url().'));
bool_url_courte = true;
}
// Si le slug n'existe pas, on le génère à la volée.
if (!this.slug) {
var slug = Variete.genSlug(this.titre_annonce);
// On va remplir le champ slug, qui doit être unique
sails.log.verbose('Après la création d\'annonce : ' + this.id);
sails.log.verbose('Le slug vaut : ' + slug);
// On va donc rechercher une annonce qui comporte
// déjà un tel slug.
// Si on ne trouve pas, on pourra faire
// attrs.slug = slug;
// Si on trouve quelque chose, alors il faudra allouer
// attrs.slug = slug + '_' + attrs.id (ce qui est le seul
// moyen facile pour obtenir une chaîne unique).
// On copie this vers ann_orig car this passe à undefined dans
// Annonce.findOne().
var ann_orig = this;
Annonce.findOne({slug: slug}, function(err1, ann) {
if (err1) {
sails.log.error(err1);
// Erreur de communication avec la BDD.
// On renvoie vers /erreur
return '/erreur';
} else if (!ann) {
// Chouette, c'est la première annonce avec ce titre.
sails.log.verbose('C\'est la première annonce de ce nom : ' + ann_orig.titre_annonce);
ann_orig.slug = slug;
ann_orig.save(function(err2) {
if (err2) {
sails.log.error('Erreur durant la sauvegarde de annonce.slug : ' + ann_orig.id + ' / ' + ann_orig.slug, err2);
// On renvoie quand-même vers /erreur
return '/erreur';
} else {
sails.log.info('Annonce /a/' + ann_orig.id + ' <---> slug = ' + ann_orig.slug);
}
});
} else {
// Malheur, on a trouvé quelque chose, donc ce
// slug n'est pas unique.
sails.log.verbose('Il existe une autre annonce avec ce titre : ' + ann_orig.titre_annonce);
ann_orig.slug = slug + '_' + ann_orig.id;
ann_orig.save(function(err4) {
if (err4) {
sails.log.error('Erreur durant la sauvegarde de annonce.slug : ' + ann_orig.id + ' / ' + ann_orig.slug, err4);
} else {
sails.log.info('Annonce /a/' + ann_orig.id + ' <---> slug = ' + ann_orig.slug);
}
});
}
});
} // fin génération du slug.
// Si la variété n'a pas de slug ou si on veut une url courte
// alors on renvoie /a/:id
// Sinon l'url est /annonce/variete.slug/annonce.slug
//
// TODO IMPORTANT : Lors du premier appel à cette fonction, il y a
// un update en base de donnée fait de manière asynchrone. Du coup,
// this.slug n'est peut-être pas encore généré. Il le sera la prochaine fois.
if (!this.slug || !this.variete.slug || bool_url_courte){
return '/a/' + this.id;
} else {
// L'annonce a ce qu'il faut
return '/annonce/' + this.variete.slug + '/' + this.slug;
}
}
},
/*
* beforeCreate() : on met à jour :
* - qte_echantillons
*
* TODO IMPORTANT : le slug n'existe pas encore. En effet, slug doit être unique,
* or pour être unique il faut pouvoir s'assurer que titre_annonce est unique.
* Si ce n'est pas le cas, on rajoute '_' + this.id.
* Malheureusement, dans beforeCreate() l'id n'est pas encore connu.
* Dans afterCreate() on ne peut plus mettre à jour l'objet, donc c'est dans
* la méthode d'instance url() qu'on en fait la mise à jour.
*
* C'est une rustine.
*/
beforeCreate: function(attrs, next) {
// Au début, la qté d'échantillons est la même
// que la qté initiale.
attrs.qte_echantillons = attrs.qte_echantillons_ini;
next();
},
afterCreate: function(attrs, next) {
next();
/*
// On va remplir le champ slug, qui doit être unique
var slug = attrs.titre_annonce.replace(/\s+/g, '-').toLowerCase();
sails.log.verbose('Après la création d\'annonce : ' + attrs.id);
sails.log.verbose('Le slug vaut : ' + slug);
// On va donc rechercher une annonce qui comporte
// déjà un tel slug.
// Si on ne trouve pas, on pourra faire
// attrs.slug = slug;
// Si on trouve quelque chose, alors il faudra allouer
// attrs.slug = slug + '_' + attrs.id (ce qui est le seul
// moyen facile pour obtenir une chaîne unique).
Annonce.findOne({slug: slug}, function(err1, ann) {
if (err1) {
sails.log.error(err1);
next(err1);
}
else if (!ann) {
// Chouette, c'est la première annonce avec ce titre.
sails.log.verbose('C\'est la première annonce de ce nom.');
Annonce.update({id:attrs.id}, {slug:slug}).exec(function(err2, object){
sails.log.error('Infinite loop ? (1)');
if (err2) next(err2);
else {
sails.log.error('Infinite loop ? (3)');
next();
}
});
//attrs.slug = slug;
//next();
} else {
// Malheur, on a trouvé quelque chose, donc ce
// slug n'est pas unique.
sails.log.verbose('Il existe une autre annonce avec ce titre.');
Annonce.update({id:attrs.id}, {slug: slug + '_' + attrs.id}).exec(function(err4, object){
sails.log.error('Infinite loop ? (2)');
if (err4) next(err4);
else next();
});
}
});
*/
},
beforeUpdate: function (attrs, next) {
// On ne met pas à jour le slug, qui doit vivre
// pendant toute la vie de l'annonce.
next();
}
};
Annonce.update()
方法您将在下面看到我目前有更新afterCreate()部分内对象的代码。请注意这不起作用。请求挂起,我看不到Infinite loop ? (*)
。检查后,我发现该过程进入// We didn't find any, so .slug is simple
行。
知道什么?我想Model.afterCreate()
更新对象的时间太晚或太早。
总结一下,我的问题实际上很简单:我想要一个独特的slug,并且添加Annonce.id
是一个很好的方法来管理。此slug用于生成具有名为ann.url()
的实例方法的URL(请参阅 this discussion )。
现在,如果我没有误解,在beforeCreate()
内部没有this.id
或attrs.id
。这就是为什么我需要在数据库中推送对象后才能创建它。
我不想在slug中添加一个随机哈希/数字,因为它会生成一个丑陋的url,并且它不能确保我得到一个独特的slug(注意我可以进入进行递归搜索,这可能没问题。
也许afterCreate()
是错误的地方,但是文档并没有明确地将其隐藏起来(由于实施或lack in documentation,我并不是唯一一个真正的问题。
我曾想过更新我的ann.url()
方法中的slug。这显然有效。但是如果我不能做任何其他事情,我将选择使用此解决方法:此方法在我的模板中随处调用,因此它是最常使用的20%代码的一部分(此项目需要相对较高的性能)。所以我不想在这个方法中再添加一个条件块。
afterCreate: function(attrs, next) {
// slug must be unique
var slug = attrs.titre_annonce.replace(/\s+/g, '-').toLowerCase();
// Let's search for a classified that would have such a slug
// If we don't find, we can do
// this.slug = slug;
// If we find sthg, we must get a unique string.
// this.slug = slug + '_' + this.id
// This would fit.
// findOne() <--- because we only want to see if there's sthg
Annonce.findOne({slug: slug}, function(err1, ann) {
if (err1) {
sails.log.error(err1);
next(err1);
}
else if (!ann) {
// We didn't find any, so .slug is simple
Annonce.update({id:attrs.id}, {slug: slug}).exec(function(err2, object){
sails.log.error('Infinite loop ? (1)');
if (err2) next(err2);
else {
sails.log.error('Infinite loop ? (3)');
next();
}
});
} else {
// We found sthg, so slug is not unique.
Annonce.update({id:attrs.id}, {slug: slug + '_' + attrs.id}).exec(function(err3, object){
sails.log.error('Infinite loop ? (2)');
if (err3) {
sails.log.error('SAVE ERROR');
next(err3);
} else next()
});
}
});
},
Annonce.find()
方法我更新了我的Model.afterCreate()以获取数据库中新创建的记录。
afterCreate: function(attrs, next) {
// slug must be unique
var slug = attrs.titre_annonce.replace(/\s+/g, '-').toLowerCase();
// Let's search for a classified that would have such a slug
// If we don't find, we can do
// this.slug = slug;
// If we find sthg, we must get a unique string.
// this.slug = slug + '_' + this.id
// This would fit.
// findOne() <--- because we only want to see if there's sthg
Annonce.findOne({slug: slug}, function(err, ann) {
if (err) {
sails.log.error(err);
next(err);
}
else if (!ann) {
// We didn't find any, so .slug is simple
Annonce.findOne({id:attrs.id}, function(error, object){
sails.log.error('Infinite loop ? (1)');
if (error) next(error);
else {
sails.log.error('Infinite loop ? (3)');
object.slug = slug;
object.save(function (err) {
sails.log.error('Infinite loop ? (4)');
next();
});
}
});
} else {
// We found sthg, so slug is not unique.
Annonce.findOne({id:attrs.id}, function(error, object){
sails.log.error('Infinite loop ? (2)');
if (error) {
sails.log.error('SAVE ERROR');
next(error);
} else {
object.slug = slug + '_' + attrs.id;
sails.log.error('SAVE OK');
object.save(function (err) {
next();
});
}
});
}
});
},
我明白了:
错误:无限循环? (1)
错误:无限循环? (3)
我没有收到任何SAVE ERROR
或SAVE OK
且请求卡住,我认为因为我们没有进入save()
而且没有next()
被调用。< / p>
那么问题是什么?
在我的某个实体中创建记录后,我必须添加一个新字段。我必须这样做,因为我需要记录的ID。
我需要保存这个,我不知道该怎么做。
afterCreate: function(obj, next) {
// slug field must be unique
var slug = obj.titre_annonce.replace(/\s+/g, '-').toLowerCase();
// Let's search for a classified that would have such a slug
// If we don't find, we can do
// this.slug = slug;
// If we find sthg, we must get a unique string.
// this.slug = slug + '_' + this.id
// This would fit.
// findOne() <--- because we only want to see if there's sthg
Annonce.findOne({slug: slug}, function(err, ann) {
if (err) {
sails.log.error(err);
next(err);
}
else if (!ann) {
// We didn't find any, so .slug is simple
obj.slug = slug;
obj.save(function(err){
next();
});
} else {
// We found sthg, so slug is not unique.
obj.slug = slug + '_' + obj.id;
obj.save(function (err) {
next();
});
}
});
错误:obj
没有save()
方法。但是没有使用.save()
结束而没有数据库更新。
您怎么看?
答案 0 :(得分:1)
在您的示例中,“obj”不会附加save方法。如果需要save方法,则需要重新实例化对象。假设“obj”来自“模型”
示例:
afterCreate : function(obj,next){
Model.findOne(obj.id, function(err, objectWithSaveMethod){
.....
}
}
或者你可以
代替obj.save()Model.update({slug:slug}, {id:obj.id}, function(err, object){
if(err) next(err);
next();
})