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