Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / docs / source / Association.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-data-Association'>/**
19 </span> * @author Ed Spencer
20  * @class Ext.data.Association
21  * @extends Object
22  *
23  * &lt;p&gt;Associations enable you to express relationships between different {@link Ext.data.Model Models}. Let's say we're
24  * writing an ecommerce system where Users can make Orders - there's a relationship between these Models that we can
25  * express like this:&lt;/p&gt;
26  *
27 &lt;pre&gt;&lt;code&gt;
28 Ext.define('User', {
29     extend: 'Ext.data.Model',
30     fields: ['id', 'name', 'email'],
31
32     hasMany: {model: 'Order', name: 'orders'}
33 });
34
35 Ext.define('Order', {
36     extend: 'Ext.data.Model',
37     fields: ['id', 'user_id', 'status', 'price'],
38
39     belongsTo: 'User'
40 });
41 &lt;/code&gt;&lt;/pre&gt;
42  *
43  * &lt;p&gt;We've set up two models - User and Order - and told them about each other. You can set up as many associations on
44  * each Model as you need using the two default types - {@link Ext.data.HasManyAssociation hasMany} and
45  * {@link Ext.data.BelongsToAssociation belongsTo}. There's much more detail on the usage of each of those inside their
46  * documentation pages. If you're not familiar with Models already, {@link Ext.data.Model there is plenty on those too}.&lt;/p&gt;
47  *
48  * &lt;p&gt;&lt;u&gt;Further Reading&lt;/u&gt;&lt;/p&gt;
49  *
50  * &lt;ul style=&quot;list-style-type: disc; padding-left: 20px;&quot;&gt;
51  *   &lt;li&gt;{@link Ext.data.HasManyAssociation hasMany associations}
52  *   &lt;li&gt;{@link Ext.data.BelongsToAssociation belongsTo associations}
53  *   &lt;li&gt;{@link Ext.data.Model using Models}
54  * &lt;/ul&gt;
55  * 
56  * &lt;b&gt;Self association models&lt;/b&gt;
57  * &lt;p&gt;We can also have models that create parent/child associations between the same type. Below is an example, where
58  * groups can be nested inside other groups:&lt;/p&gt;
59  * &lt;pre&gt;&lt;code&gt;
60
61 // Server Data
62 {
63     &quot;groups&quot;: {
64         &quot;id&quot;: 10,
65         &quot;parent_id&quot;: 100,
66         &quot;name&quot;: &quot;Main Group&quot;,
67         &quot;parent_group&quot;: {
68             &quot;id&quot;: 100,
69             &quot;parent_id&quot;: null,
70             &quot;name&quot;: &quot;Parent Group&quot;
71         },
72         &quot;child_groups&quot;: [{
73             &quot;id&quot;: 2,
74             &quot;parent_id&quot;: 10,
75             &quot;name&quot;: &quot;Child Group 1&quot;
76         },{
77             &quot;id&quot;: 3,
78             &quot;parent_id&quot;: 10,
79             &quot;name&quot;: &quot;Child Group 2&quot;
80         },{
81             &quot;id&quot;: 4,
82             &quot;parent_id&quot;: 10,
83             &quot;name&quot;: &quot;Child Group 3&quot;
84         }]
85     }
86 }
87
88 // Client code
89 Ext.define('Group', {
90     extend: 'Ext.data.Model',
91     fields: ['id', 'parent_id', 'name'],
92     proxy: {
93         type: 'ajax',
94         url: 'data.json',
95         reader: {
96             type: 'json',
97             root: 'groups'
98         }
99     },
100     associations: [{
101         type: 'hasMany',
102         model: 'Group',
103         primaryKey: 'id',
104         foreignKey: 'parent_id',
105         autoLoad: true,
106         associationKey: 'child_groups' // read child data from child_groups
107     }, {
108         type: 'belongsTo',
109         model: 'Group',
110         primaryKey: 'id',
111         foreignKey: 'parent_id',
112         autoLoad: true,
113         associationKey: 'parent_group' // read parent data from parent_group
114     }]
115 });
116
117
118 Ext.onReady(function(){
119     
120     Group.load(10, {
121         success: function(group){
122             console.log(group.getGroup().get('name'));
123             
124             group.groups().each(function(rec){
125                 console.log(rec.get('name'));
126             });
127         }
128     });
129     
130 });
131  * &lt;/code&gt;&lt;/pre&gt;
132  *
133  */
134 Ext.define('Ext.data.Association', {
135 <span id='Ext-data-Association-cfg-ownerModel'>    /**
136 </span>     * @cfg {String} ownerModel The string name of the model that owns the association. Required
137      */
138
139 <span id='Ext-data-Association-cfg-associatedModel'>    /**
140 </span>     * @cfg {String} associatedModel The string name of the model that is being associated with. Required
141      */
142
143 <span id='Ext-data-Association-cfg-primaryKey'>    /**
144 </span>     * @cfg {String} primaryKey The name of the primary key on the associated model. Defaults to 'id'.
145      * In general this will be the {@link Ext.data.Model#idProperty} of the Model.
146      */
147     primaryKey: 'id',
148
149 <span id='Ext-data-Association-cfg-reader'>    /**
150 </span>     * @cfg {Ext.data.reader.Reader} reader A special reader to read associated data
151      */
152     
153 <span id='Ext-data-Association-cfg-associationKey'>    /**
154 </span>     * @cfg {String} associationKey The name of the property in the data to read the association from.
155      * Defaults to the name of the associated model.
156      */
157
158     defaultReaderType: 'json',
159
160     statics: {
161         create: function(association){
162             if (!association.isAssociation) {
163                 if (Ext.isString(association)) {
164                     association = {
165                         type: association
166                     };
167                 }
168
169                 switch (association.type) {
170                     case 'belongsTo':
171                         return Ext.create('Ext.data.BelongsToAssociation', association);
172                     case 'hasMany':
173                         return Ext.create('Ext.data.HasManyAssociation', association);
174                     //TODO Add this back when it's fixed
175 //                    case 'polymorphic':
176 //                        return Ext.create('Ext.data.PolymorphicAssociation', association);
177                     default:
178                         //&lt;debug&gt;
179                         Ext.Error.raise('Unknown Association type: &quot;' + association.type + '&quot;');
180                         //&lt;/debug&gt;
181                 }
182             }
183             return association;
184         }
185     },
186
187 <span id='Ext-data-Association-method-constructor'>    /**
188 </span>     * Creates the Association object.
189      * @param {Object} config (optional) Config object.
190      */
191     constructor: function(config) {
192         Ext.apply(this, config);
193
194         var types           = Ext.ModelManager.types,
195             ownerName       = config.ownerModel,
196             associatedName  = config.associatedModel,
197             ownerModel      = types[ownerName],
198             associatedModel = types[associatedName],
199             ownerProto;
200
201         //&lt;debug&gt;
202         if (ownerModel === undefined) {
203             Ext.Error.raise(&quot;The configured ownerModel was not valid (you tried &quot; + ownerName + &quot;)&quot;);
204         }
205         if (associatedModel === undefined) {
206             Ext.Error.raise(&quot;The configured associatedModel was not valid (you tried &quot; + associatedName + &quot;)&quot;);
207         }
208         //&lt;/debug&gt;
209
210         this.ownerModel = ownerModel;
211         this.associatedModel = associatedModel;
212
213 <span id='Ext-data-Association-property-ownerName'>        /**
214 </span>         * The name of the model that 'owns' the association
215          * @property ownerName
216          * @type String
217          */
218
219 <span id='Ext-data-Association-property-associatedName'>        /**
220 </span>         * The name of the model is on the other end of the association (e.g. if a User model hasMany Orders, this is 'Order')
221          * @property associatedName
222          * @type String
223          */
224
225         Ext.applyIf(this, {
226             ownerName : ownerName,
227             associatedName: associatedName
228         });
229     },
230
231 <span id='Ext-data-Association-method-getReader'>    /**
232 </span>     * Get a specialized reader for reading associated data
233      * @return {Ext.data.reader.Reader} The reader, null if not supplied
234      */
235     getReader: function(){
236         var me = this,
237             reader = me.reader,
238             model = me.associatedModel;
239
240         if (reader) {
241             if (Ext.isString(reader)) {
242                 reader = {
243                     type: reader
244                 };
245             }
246             if (reader.isReader) {
247                 reader.setModel(model);
248             } else {
249                 Ext.applyIf(reader, {
250                     model: model,
251                     type : me.defaultReaderType
252                 });
253             }
254             me.reader = Ext.createByAlias('reader.' + reader.type, reader);
255         }
256         return me.reader || null;
257     }
258 });
259 </pre>
260 </body>
261 </html>