/** * This class and its derivatives describe how two entities are related to each other. * Associations have the following forms: * * * *{@link Ext.data.schema.ManyToOne many-to-one}* * * *{@link Ext.data.schema.ManyToMany many-to-many}* * * *{@link Ext.data.schema.OneToOne one-to-one}* * * Associations are first-class objects in a `{@link Ext.data.schema.Schema schema}` but * are not created directly. They are created based on {@link Ext.data.field.Field#reference} * properties but also on {@link Ext.data.schema.ManyToMany} declarations. * * Associations have unique names within the `schema` as do {@link Ext.data.Model entities}. * In many cases, the association names can be generated. These names have uses beyond the * basic needs of tracking such as when communicating with the server. If the generated * names are not satisfactory, they can be given explicitly or the default naming can be * replaced by implementing a custom `Ext.data.schema.Schema` class. * * # Life Cycle * * Intimately connected with many associations is the concept of life-cycle. It is often * the case that one entity is "owned" by another so that if the owner is to be deleted, * the owned entity must also be deleted. * * There are also associations that work in the reverse direction. That is, the presence of * an associated entity prevents the other entity from being deleted. * * Finally, some associations just need to be dissolved if one of the related entities is * deleted. This is the case in a {@link Ext.data.schema.ManyToMany many-to-many} * association, but can also be for others if the `reference` field can be set to `null`. * * # Left and Right * * Because associations are data that span entity types, they are not rightly viewed as * "belonging" to either entity. Instead, associations are owned by the `Schema`. Even so, * because belonging to an association effects both entities, associations are often * viewed from two perspectives or "sides". To distinguish them we call one "left" and the * other "right". * * The reason for this choice derives from {@link Ext.data.schema.ManyToMany many-to-many} * associations and their typical underlying "matrix" table. If you were to view the matrix * table in a grid, you would see one id on the left and the other id on the right. There * is no further significance to these labels. * * While the concept of left and right might makes sense in a matrix relationship, the * labels also apply to the other relationships. In those cases, the "left" entity is the * entity that contains the {@link Ext.data.Field#reference} (or foreign key). * * # Example * * To help illustrate the various associations, consider a data model with Users, Groups * and Organizations. The Users are owned by an Organization. Deleting an Organization, * should delete all of the Users it contains. The Users can also be added to one or more * Groups, for example, the "moderator" or "admin" Group. Further, a a Level is assigned * to each User. Levels represent the subscriber's or customer's rank, such as "premium" * or "basic". * * To summarize: * * * Users are *{@link Ext.data.schema.ManyToOne many-to-one}* to Organizations * * Users are *{@link Ext.data.schema.ManyToOne many-to-one}* to Levels * * Users are *{@link Ext.data.schema.ManyToMany many-to-many}* to Groups */Ext.define('Ext.data.schema.Association', { requires: [ 'Ext.data.schema.Role' ], isOneToOne: false, isManyToOne: false, isManyToMany: false, /** * @cfg {String} name * The name of this association. */ /** * @property {Object} owner * Points at either `left` or `right` objects if one is the owning party in this * association or is `null` if there is no owner. * @readonly */ owner: null, /** * @property {Ext.Class} definedBy * @readonly */ /** * @property {Ext.data.field.Field} field * @readonly */ field: null, /** * @property {Ext.data.schema.Schema} schema * @readonly */ /** * @property {Boolean} nullable * @readonly */ /** * @property {Ext.data.schema.Role} left * @readonly */ /** * @property {Ext.data.schema.Role} right * @readonly */ constructor: function (config) { var me = this, left, right; Ext.apply(me, config); me.left = left = new me.Left(me, me.left); me.right = right = new me.Right(me, me.right); left.inverse = right; right.inverse = left; }, hasField: function() { return !!this.field; }, getFieldName: function() { var field = this.field; return field ? field.name : ''; }});