Upgrade to ExtJS 4.0.1 - Released 05/18/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-method-constructor'><span id='Ext-data-Association'>/**
19 </span></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  * @constructor
134  * @param {Object} config Optional config object
135  */
136 Ext.define('Ext.data.Association', {
137 <span id='Ext-data-Association-cfg-ownerModel'>    /**
138 </span>     * @cfg {String} ownerModel The string name of the model that owns the association. Required
139      */
140
141 <span id='Ext-data-Association-cfg-associatedModel'>    /**
142 </span>     * @cfg {String} associatedModel The string name of the model that is being associated with. Required
143      */
144
145 <span id='Ext-data-Association-cfg-primaryKey'>    /**
146 </span>     * @cfg {String} primaryKey The name of the primary key on the associated model. Defaults to 'id'.
147      * In general this will be the {@link Ext.data.Model#idProperty} of the Model.
148      */
149     primaryKey: 'id',
150
151 <span id='Ext-data-Association-cfg-reader'>    /**
152 </span>     * @cfg {Ext.data.reader.Reader} reader A special reader to read associated data
153      */
154     
155 <span id='Ext-data-Association-cfg-associationKey'>    /**
156 </span>     * @cfg {String} associationKey The name of the property in the data to read the association from.
157      * Defaults to the name of the associated model.
158      */
159
160     defaultReaderType: 'json',
161
162     statics: {
163         create: function(association){
164             if (!association.isAssociation) {
165                 if (Ext.isString(association)) {
166                     association = {
167                         type: association
168                     };
169                 }
170
171                 switch (association.type) {
172                     case 'belongsTo':
173                         return Ext.create('Ext.data.BelongsToAssociation', association);
174                     case 'hasMany':
175                         return Ext.create('Ext.data.HasManyAssociation', association);
176                     //TODO Add this back when it's fixed
177 //                    case 'polymorphic':
178 //                        return Ext.create('Ext.data.PolymorphicAssociation', association);
179                     default:
180                         //&lt;debug&gt;
181                         Ext.Error.raise('Unknown Association type: &quot;' + association.type + '&quot;');
182                         //&lt;/debug&gt;
183                 }
184             }
185             return association;
186         }
187     },
188
189     constructor: function(config) {
190         Ext.apply(this, config);
191
192         var types           = Ext.ModelManager.types,
193             ownerName       = config.ownerModel,
194             associatedName  = config.associatedModel,
195             ownerModel      = types[ownerName],
196             associatedModel = types[associatedName],
197             ownerProto;
198
199         //&lt;debug&gt;
200         if (ownerModel === undefined) {
201             Ext.Error.raise(&quot;The configured ownerModel was not valid (you tried &quot; + ownerName + &quot;)&quot;);
202         }
203         if (associatedModel === undefined) {
204             Ext.Error.raise(&quot;The configured associatedModel was not valid (you tried &quot; + associatedName + &quot;)&quot;);
205         }
206         //&lt;/debug&gt;
207
208         this.ownerModel = ownerModel;
209         this.associatedModel = associatedModel;
210
211 <span id='Ext-data-Association-property-ownerName'>        /**
212 </span>         * The name of the model that 'owns' the association
213          * @property ownerName
214          * @type String
215          */
216
217 <span id='Ext-data-Association-property-associatedName'>        /**
218 </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')
219          * @property associatedName
220          * @type String
221          */
222
223         Ext.applyIf(this, {
224             ownerName : ownerName,
225             associatedName: associatedName
226         });
227     },
228
229 <span id='Ext-data-Association-method-getReader'>    /**
230 </span>     * Get a specialized reader for reading associated data
231      * @return {Ext.data.reader.Reader} The reader, null if not supplied
232      */
233     getReader: function(){
234         var me = this,
235             reader = me.reader,
236             model = me.associatedModel;
237
238         if (reader) {
239             if (Ext.isString(reader)) {
240                 reader = {
241                     type: reader
242                 };
243             }
244             if (reader.isReader) {
245                 reader.setModel(model);
246             } else {
247                 Ext.applyIf(reader, {
248                     model: model,
249                     type : me.defaultReaderType
250                 });
251             }
252             me.reader = Ext.createByAlias('reader.' + reader.type, reader);
253         }
254         return me.reader || null;
255     }
256 });
257 </pre>
258 </body>
259 </html>