<commit_before>(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    define(['underscore', 'backbone', 'herit'], factory);
  } else if (typeof exports !== 'undefined') {
    module.exports =
      factory(require('underscore'), require('backbone'), require('herit'));
  } else {
    root.BackboneRelations = factory(root._, root.Backbone, root.herit);
  }
})(this, function (_, Backbone, herit) {
  'use strict';

  var proto = Backbone.Model.prototype;
  var get = proto.get;
  var set = proto.set;

  var Relation = function (owner, key, options) {
    _.extend(this, options);
    this.owner = owner;
    this.key = key;
    if (this.via) {
      var split = this.via.split('#');
      this.via = split[0];
      this.viaKey = split[1] || key;
    }
  };

  _.extend(Relation.prototype, {
    get: function () { return this.instance(); },

    set: function (val, options) {
      options = _.extend({}, options, {add: true, merge: true, remove: true});
      this.instance().set(val || (this.hasOne ? {} : []), options);
    },

    resolve: function () {
      if (!this.via) return this.get();
      var via = this.owner.relations[this.via];
      var method = via.hasOne ? 'get' : 'pluck';
      var resolved = this.owner.resolve(this.via)[method](this.viaKey);
      if (this.hasOne) return resolved;
      return new this.hasMany(
        resolved[0] instanceof this.hasMany ?
        _.flatten(_.pluck(resolved, 'models')) :
        resolved
      );
    }
  });

  var HasOneRelation = herit(Relation, {
    instance: function () {
      if (this._instance) return this._instance;
      var Model = this.hasOne;
      var Collection = Backbone.Collection.extend({model: Model});
      var owner = this.owner;
      var fk = this.fk;
      var reverse = this.reverse;
      var instance = this._instance = new Collection({id: owner.get(fk)});
      var idAttr = Model.prototype.idAttribute;
      instance.on('add change:' + idAttr, function (model, __, options) {
        owner.set(fk, model.id, options);
      });
      owner.on('change:' + fk, function (__, val, options) {
        if (instance.first().id !== val) {
          instance.set(new Model({id: val}), options);
        }
      });
      if (reverse) {
        instance.on({
          add: function (model, __, options) {
            model.get(reverse).add(owner, options);
          },
          remove: function (model, __, options) {
            model.get(reverse).remove(owner, options);
          }
        });
      }
      return instance;
    },

    get: function () { return this.instance().first(); }
  });

  var HasManyRelation = herit(Relation, {
    instance: function () {
      if (this._instance) return this._instance;
      var instance = this._instance = new this.hasMany();
      var owner = instance.owner = this.owner;
      instance.fk = this.fk;
      instance.urlRoot = this.urlRoot || '/' + this.key;
      instance.url = this.url || function () {<commit_msg>Work with idAttributes other than id<commit_after>(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    define(['underscore', 'backbone', 'herit'], factory);
  } else if (typeof exports !== 'undefined') {
    module.exports =
      factory(require('underscore'), require('backbone'), require('herit'));
  } else {
    root.BackboneRelations = factory(root._, root.Backbone, root.herit);
  }
})(this, function (_, Backbone, herit) {
  'use strict';

  var proto = Backbone.Model.prototype;
  var get = proto.get;
  var set = proto.set;

  var Relation = function (owner, key, options) {
    _.extend(this, options);
    this.owner = owner;
    this.key = key;
    if (this.via) {
      var split = this.via.split('#');
      this.via = split[0];
      this.viaKey = split[1] || key;
    }
  };

  _.extend(Relation.prototype, {
    get: function () { return this.instance(); },

    set: function (val, options) {
      options = _.extend({}, options, {add: true, merge: true, remove: true});
      this.instance().set(val || (this.hasOne ? {} : []), options);
    },

    resolve: function () {
      if (!this.via) return this.get();
      var via = this.owner.relations[this.via];
      var method = via.hasOne ? 'get' : 'pluck';
      var resolved = this.owner.resolve(this.via)[method](this.viaKey);
      if (this.hasOne) return resolved;
      return new this.hasMany(
        resolved[0] instanceof this.hasMany ?
        _.flatten(_.pluck(resolved, 'models')) :
        resolved
      );
    }
  });

  var HasOneRelation = herit(Relation, {
    instance: function () {
      if (this._instance) return this._instance;
      var Model = this.hasOne;
      var Collection = Backbone.Collection.extend({model: Model});
      var owner = this.owner;
      var fk = this.fk;
      var reverse = this.reverse;
      var idAttr = Model.prototype.idAttribute;
      var attrs = {};
      attrs[idAttr] = owner.get(fk);
      var instance = this._instance = new Collection(attrs);
      instance.on('add change:' + idAttr, function (model, __, options) {
        owner.set(fk, model.id, options);
      });
      owner.on('change:' + fk, function (__, val, options) {
        if (instance.first().id === val) return;
        attrs[idAttr] =  val;
        instance.set(new Model(attrs), options);
      });
      if (reverse) {
        instance.on({
          add: function (model, __, options) {
            model.get(reverse).add(owner, options);
          },
          remove: function (model, __, options) {
            model.get(reverse).remove(owner, options);
          }
        });
      }
      return instance;
    },

    get: function () { return this.instance().first(); }
  });

  var HasManyRelation = herit(Relation, {
    instance: function () {
      if (this._instance) return this._instance;
      var instance = this._instance = new this.hasMany();
      var owner = instance.owner = this.owner;
      instance.fk = this.fk;
      instance.urlRoot = this.urlRoot || '/' + this.key;
      instance.url = this.url || function () {
{'fraction_non_alphanumeric': 0.15864909390444812, 'fraction_numerical': 0.0009884678747940692, 'mean_word_length': 2.5255516840882692, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1266029', 'n_tokens_mistral': 1869, 'n_tokens_neox': 1843, 'n_words': 442}