I've been using ember-changeset at work for a handful of forms, and it works great! However, tracking hasMany
relationships can be a little tricky.
This post is based on version 1.3.0 of ember-changeset, which I believe is the most stable version at the time of this writing.
Let's say we have a form where we are applying tags to a post. If we look at the README or the example demo, there aren't examples of tracking hasMany
relationship changes. If we are doing this without a changeset, we might do something like the following, as suggested in the Ember Guides:
post.get('tags').pushObject(tag);
or if we're removing a tag:
post.get('tags').removeObject(tag);
We might think to try:
postChangeset.get('tags').pushObject(tag);
But this approach has some subtle issues. The issue here is that the changeset won't track the changes to the tags
relationship because we are modifying the hasMany
reference directly. Thus, we won't see tags
in changeset.get('change')
, and changeset properties like isInvalid
won't work the way we expect.
Here has been my solution:
export function addToHasMany(changeset, relationship, item) {
let hasMany = changeset.get(relationship).pushObjects([item]);
changeset.set(relationship, hasMany.toArray());
}
export function removeFromHasMany(changeset, relationship, item) {
let hasMany = changeset.get(relationship).removeObject(item);
changeset.set(relationship, hasMany.toArray());
}
Then, we can do the following in an action:
addToHasMany(changeset, 'tags', tag);
removeFromHasMany(changeset, 'tags', tag);
These utility functions do what we did before but then call changeset.set()
with a new array reference via toArray()
.
Note that pushObjects
was used instead of pushObject
. This is because pushObjects
returns the array reference whereas pushObject
returns the same object that was passed to it as a param.
Another thing to note about this solution is that the changeset won't keep track of which items have been added and which items have been removed from the relationship. Personally I haven't needed that level of detail in the forms I've been building.
Have you dealt with tracking hasMany
relationship changes differently? Let me know on Twitter!