code: function setAttr(setModel, newValue, setOptions) {
        var oldValue = model._containedModels[attrName];
  
        // Pass through if removing
        if (newValue === undefined || newValue === null) {
          model._containedModels[attrName] = newValue;
          return;
        }
  
        // Is the new value the correct type?
        if (newValue instanceof Ctor) {
  
          // Directly set if no old value
          if (!oldValue instanceof Ctor) {
            model._containedModels[attrName] = newValue;
            return;
          }
  
          // They're both models.  Disregard if they're the same.
          var oldJSON = oldValue.toJSON({deep:true});
          var newJSON = newValue.toJSON({deep:true});
          if (_.isEqual(oldJSON, newJSON)) {
            return;
          }
  
          // Merge the raw JSON if they're both models
          newValue = newJSON;
        }
  
        // Keep the previous model and merge new data into it
        // For collections this relies on the Collection.set() method
        if (oldValue instanceof Ctor) {
          model.attributes[attrName] = oldValue;
          model._currentAttributes[attrName] = oldValue;
          model.changed[attrName] = oldValue;
          oldValue.set(newValue, setOptions);
          return;
        }
  
        // Create a new model or collection, passing the value
        newValue =
          model._containedModels[attrName] =
          model.attributes[attrName] =
          model._currentAttributes[attrName] =
          new Ctor(newValue, setOptions);
  
        // Watch for changes to the underlying model or collection
        // (collection add/remove), forwarding changes to this model
        newValue.on('change add remove reset', UI.onSubModelChange, {
          parent:model,
          attrName: attrName
        });
      }
docs: Build the function for setting model data