Take the 2-minute tour ×

I would like to make sure that a specific attribute is unique across the collection when a new model is created so that I can ultimately use this attribute as a permalink.

I have a List Collection and List Model. (CoffeeScript)

class App.Models.List extends Backbone.Model
    name: "My New List"

class App.Collections.ListSet extends Backbone.Model
  model: App.Models.List

When a new model is added to the ListSet, I would like to add a auto-incrementing number to the end of the name attribute if a model exists with that name already. For example My New List 1 if a model existed with My New List.

I don't want it to be obtrusive and show an error, but just fix the problem automatically. I am happy with the logic behind adding the incrementing integer, but I need direction on where to put the code to make the changes.

share|improve this question
Perhaps (appending) the model's cid might stand in for your uses? documentcloud.github.com/backbone/#Model-cid –  rjz Jul 10 '12 at 12:18
I don't think you're going to be able to get uniqueness until you talk to your server. Unless you only want uniqueness per-user and you want to assume that a user will only be using one instance of your application at a time. –  mu is too short Jul 10 '12 at 16:13
Yeah I only want uniqueness per each users set of lists. Assume for the time being that there was only one instance of the app, how would you do it? –  Nick Jul 10 '12 at 16:48
add comment

2 Answers

up vote 1 down vote accepted

This might work for you:

App.Models.List = Backbone.Model.extend({
    initialize: function(attrs) {
        this.set({originalName: attrs.name});

        var count = yourCollection.reduce(function(count,model){
            return count + (model.get('originalName') === this.get('originalName') ? 1 : 0);

        if(count > 0) {
            this.set({name: this.get('name') + ' ' + count});

Here's a demo: jsFiddle DEMO

What this should do is every time you initialize a model, you scan your collection to see if any other models have that same originalName. If so, you tack on the result to the name attribute.

=== UPDATE ===

I realize now that it's probably better to do the modification when the model is added to the collection, so as to decouple the model from the collection. Here's an updated code snippet:

App.Models.List = Backbone.Model.extend({
    initialize: function(attrs) {
        this.set({originalName: attrs.name});

App.Collections.Lists = Backbone.Collection.extend({
    model: App.Models.List,
    initialize: function() {
    resolveNameConflict: function(model){
        var count = this.reduce(function(c,m){
            return c + (m.get('originalName') === model.get('originalName') ? 1 : 0);
        if(count > 1) {
            model.set({name: model.get('originalName') + ' ' + (count-1)});

and a demo: jsFiddle DEMO

share|improve this answer
And now I learned a good way to use the reduce function. I'm in favor of this answer. :-) The only caveat to this answer is if I add model with name listName_2 and the list already has two list items with the originalName, this model name will change to listName_3. Come to think of it, I think these solutions MUST assume that one has the entire collection at start. –  orangewarp Jul 16 '12 at 20:05
@orangewarp The originalName attribute is set equal to the name attribute when the model is created. If you manually set the name to be "listName 2", then it will not change if there already exists 2 other models with an originalName of "listName". The real caveat to this solution is that if you create a new model with the name "ListName 2", it will not check to see if a model already exists which had its name changed to "ListName 2" by the resolveNameConflict function. –  jackwanders Jul 16 '12 at 20:31
Ah. I neglected to really read the model code! :-P This solution would still require all models of the collection to be in place at start right? If I have 4 models in the DB but the way my app is set up I can add them individually - let's say I add 3... then if I add a new model it won't know about listName_4 and now we have two models with the same name. So maybe this is caveat number two. –  orangewarp Jul 16 '12 at 23:56
@orangewarp I'm not sure I follow. My answer assumes you're not manually creating models with IDs suffixed to their names. See this demo: jsfiddle.net/446hV/7 I'm creating models at run-time and adding them to the collection. The output shows that the names are correctly adjusted, while the original names remain intact –  jackwanders Jul 17 '12 at 12:54
sorry for confusion. Yes. It works if we always start with an empty collection and create/add NEW models. It also works if we have a reset/fetch ALL existing models before creating new models. What I'm saying (maybe unimportant) is that if we're building these collections by picking and choosing existing models, it could fall apart. Using your example lets say I make a new collection and add the persisted models with modName Jack and Jack 1. Then I create a new model with origName Jack. The modName will become Jack 2. Conflict with the model that has been persisted to the server. –  orangewarp Jul 17 '12 at 20:04
show 3 more comments

UPDATE: jackwander's answer is a better solution... I'm going to keep this here though because it's interesting to compare and contrast my naive solution to his. Beginner programmers, you can learn something by evaluating the two. :-)

I'll take a stab at it. You might do something like this. Basically we add an eventListener that does a name check every time you add a model to the collection. The nameTracking array is a sort of catalogue of name objects that have a unique name fragment and the counter which keeps track of what the last count of the name root is. Useful for our incrementing application.

ListSet = Backbone.Collection.extend({

    initialize: function() {
        this.nameTracking = [];
        this.on('add', this.pushModelName, this);

    pushModelName: function(model, collection) {

        // First, look through current collection for a model with same name
        var duplicate = this.find(function(listModel) {
            return model.get('name') === listModel.get('name');

        // If duplicate exists, we lookup the name and counter in the nameTracking array.
        if (duplicate) {

            var nameObj = _.find(this.nameTracking, function(nameObj) {
                return nameObj.name === model.get('name');

            // We increment the counter so that our added model is appended with the
            // correct, "latest" increment/indicator
            nameObj.count = nameObj.count++;
            model.set('name', model.get('name') + '_' + nameObj.count);

        // Otherwise it doesn't exist so we push the name into our nameTracking array
        } else {    // Not a duplicate, new name

            var modelName = model.get('name');

                'name': modelName,
                'count': 0


Thing to note is that this assumes the model you're adding is a new model and not one that already has an id of a model that already exists in collection (not a clone.) You'd also want some way to update the nameTracking[] on collection initialization or fetch() because this assumes you're starting from scratch. I don't deal with removal of models and updating the name counter stuff but based on this sketch it shouldn't be hard to implement if you desire something of that nature.

share|improve this answer
What do you think? –  orangewarp Jul 16 '12 at 18:33
add comment

Your Answer


