I want to assign multiple tags to an article.
Here are my Models
App.Article = DS.Model.extend({
title: DS.attr('string'),
body: DS.attr('string')
articleTags: DS.hasMany('articleTag', {async: true})
});
App.NewsArticle = App.Article.extend({
});
App.ArticleTag = DS.Model.extend({
tag: DS.belongsTo('tag', {async: true}),
article: DS.belongsTo('article', {async: true})
});
App.Tag = DS.Model.extend({
title: DS.attr('string'),
articleTags: DS.hasMany('articleTag', {async: true})
});
I’m using this apporach to persisting relationship between tags (persisted or not) and persisted article.
all articles’ class used in those approach is NewsArticle
, not Article
- persist article using save()
- get article’s articleTags
- get each articleTag’s tag.
- persist those tags using save()
- persist article’s articleTags with save()
The code is like below.
var article, tagPromiseArray, tagSavePromiseArray, articleTagsOfArticle;
article = this.controller.get('model');
article.save().then(function() {
return article.get('articleTags');
}.bind(this)).then(function(articleTags) {
articleTagsOfArticle = articleTags;
tagPromiseArray = articleTags.map(function(articleTag) {
return articleTag.get('tag');
}, this);
return Ember.RSVP.all(tagPromiseArray)
}.bind(this)).then(function(tags) {
tagSavePromiseArray = tags.map(function(tag) {
return tag.save();
}, this);
return Ember.RSVP.all(tagSavePromiseArray)
}.bind(this)).then(function(tags) {
return articleTagsOfArticle.save();
}.bind(this)).then(function() {
this.controller.set("flashSuccess", "Successfully modified.");
this.transitionTo('index');
}.bind(this));
This works fine even though it use a lot of server request.
But it doesn’t work when I use this approach to not persisted article.
after I call article.save()
on the new article, length of articleTags for the article become 0. so I think relationship is broken when I call article.save()… but why?
article.get('articleTags').then(function(articleTags) {
console.log(articleTags); // its length is 0 after I call article.save()
})
So I did another apporach for persisting new article,
-
get articleTag of the article
-
get each articleTag’s tag
-
persist those tags using save().
-
get articleTag of the article once again
-
persist them with seperate save() promises and assign return value to
this.articleTagsThatShouldBeAssociatedWithArticle
(because raw ‘articleTags’ recordArray gets empty after article.save() called) -
persist article using save()
-
associate each articleTag in
this.articleTagsThatShouldBeAssociatedWithArticle
with article and persist them.article.get('articleTags').then(function(articleTags) { return this.getTagsFromArticleTags(articleTags) }.bind(this)).then(function(tags) { return this.saveTags(tags); }.bind(this)).then(function() { return article.get('articleTags'); }.bind(this)).then(function(articleTags) { return this.saveArticleTags(articleTags); }.bind(this)).then(function(articleTags) { this.set('articleTagsThatShouldBeAssociatedWithArticle', articleTags); return article.save(); }.bind(this)).then(function(article) { return this.associateArticleTagsWith(article); }.bind(this)).then(function() { this.controller.set('flashSuccess', 'Successfully created.'); this.controllerFor('index').set('page', 1); this.transitionTo('index'); }.bind(this));
but This doens’t work either. I checked my server log, and realized that when attempting to persist association between articleTags and article. my server request doesn’t include article_id… even though articleTag.set(‘article’, article) is properly set.
What am I doing wrong? What is the best practices for persisting many to many association?