Skip to content
This repository
Browse code

Datamodel documentation fixes

Fixes reported issues and other related typos, inconsistent language from the datamodel documentation. Thanks to Nimo.
  • Loading branch information...
commit eb82094c4505e457cdec7e874032633e5b40cd32 1 parent d774cb5
Will Rossiter authored August 03, 2012

Showing 1 changed file with 92 additions and 73 deletions. Show diff stats Hide diff stats

  1. 165  docs/en/topics/datamodel.md
165  docs/en/topics/datamodel.md
Source Rendered
@@ -40,8 +40,15 @@ are `filter()` and `sort()`:
40 40
 	$members = Member::get()->filter(array('FirstName' => 'Sam'))->sort('Surname');
41 41
 	
42 42
 Those of you who know a bit about SQL might be thinking "it looks like you're querying all members, and then filtering
43  
-to those with a first name of 'Sam'. Isn't this very slow?"  Is isn't, because the ORM doesn't actually execute the 
44  
-query until you iterate on the result with a `foreach()` or `<% loop %>`.
  43
+to those with a first name of 'Sam'. Isn't this very slow?"  Is isn't, because the ORM doesn't actually execute the SQL
  44
+query until you iterate on the result with a `foreach()` or `<% loop %>`. The ORM is smart enough to generate a single 
  45
+efficient query at the last moment in time without needing to post process the result set in PHP. In MySQL the query 
  46
+generated by the ORM may look something like this for the previous query.
  47
+
  48
+	:::
  49
+	SELECT * FROM Member WHERE FirstName = 'Sam' ORDER BY Surname
  50
+
  51
+An example of the query process in action:
45 52
 
46 53
 	:::php
47 54
 	// The SQL query isn't executed here...
@@ -60,14 +67,16 @@ This also means that getting the count of a list of objects will be done with a
60 67
 
61 68
 	:::php
62 69
 	$members = Member::get()->filter(array('FirstName' => 'Sam'))->sort('Surname');
63  
-	// This will create an single SELECT COUNT query.
  70
+	
  71
+	// This will create an single SELECT COUNT query similar to -
  72
+	// SELECT COUNT(*) FROM Members WHERE FirstName = 'Sam'
64 73
 	echo $members->Count();
65 74
 	
66  
-All of this lets you focus on writing your application, and not worrying too much about whether or not your queries are efficient.
67 75
 
68 76
 ### Returning a single DataObject
69 77
 
70  
-There are a couple of ways of getting a single DataObject from the ORM.  If you know the ID number of the object, you can use `byID($id)`:
  78
+There are a couple of ways of getting a single DataObject from the ORM.  If you know the ID number of the object, 
  79
+you can use `byID($id)`:
71 80
 
72 81
 	:::php
73 82
 	$member = Member::get()->byID(5);
@@ -80,12 +89,12 @@ If you have constructed a query that you know should return a single record, you
80 89
 
81 90
 ### Sort
82 91
 
83  
-Quiet often you would like to sort a list. Doing this on a list could be done in a few ways.
  92
+Quite often you would like to sort a list. Doing this on a list could be done in a few ways.
84 93
 
85 94
 If would like to sort the list by `FirstName` in a ascending way (from A to Z).
86 95
 
87 96
 	:::php
88  
-	$member = Member::get()->sort('FirstName', 'ASC');
  97
+	$member = Member::get()->sort('FirstName', 'ASC'); // ASC or DESC
89 98
 	$member = Member::get()->sort('FirstName'); // Ascending is implied
90 99
 
91 100
 To reverse the sort
@@ -93,7 +102,8 @@ To reverse the sort
93 102
 	:::php
94 103
 	$member = Member::get()->sort('FirstName', 'DESC');
95 104
 
96  
-However you might have several entries with the same `FirstName` and would like to sort them by `FirstName` and `LastName`
  105
+However you might have several entries with the same `FirstName` and would like to sort them by `FirstName` 
  106
+and `LastName`
97 107
 
98 108
 	:::php
99 109
 	$member = Member::get()->sort(array(
@@ -101,9 +111,14 @@ However you might have several entries with the same `FirstName` and would like
101 111
 		'LastName'=>'ASC'
102 112
 	));
103 113
 
  114
+You can also sort randomly
  115
+
  116
+	:::php
  117
+	$member = Member::get()->sort('RAND()')
  118
+	
104 119
 ### Filter
105 120
 
106  
-As you might expect, the `filter()` method filters the list of objects that gets returned.  The previous example 
  121
+As you might expect, the `filter()` method filters the list of objects that gets returned. The previous example 
107 122
 included this filter, which returns all Members with a first name of "Sam".
108 123
 
109 124
 	:::php
@@ -113,8 +128,8 @@ In SilverStripe 2, we would have passed `"\"FirstName\" = 'Sam'` to make this qu
113 128
 `array('FirstName' => 'Sam')`, to minimise the risk of SQL injection bugs.  The format of this array follows a few 
114 129
 rules:
115 130
 
116  
- * Each element of the array specifies a filter.  You can specify as many filters as you like, and they **all** must be 
117  
-true.
  131
+ * Each element of the array specifies a filter.  You can specify as many filters as you like, and they **all** must 
  132
+ be true.
118 133
  * The key in the filter corresponds to the field that you want to filter by.
119 134
  * The value in the filter corresponds to the value that you want to filter to.
120 135
 
@@ -126,7 +141,7 @@ So, this would return only those members called "Sam Minnée".
126 141
 		'Surname' => 'Minnée',
127 142
 	));
128 143
 
129  
-There are also a short hand way of getting Members with the FirstName of Sam.
  144
+There is also a short hand way of getting Members with the FirstName of Sam.
130 145
 
131 146
 	:::php
132 147
 	$members = Member::get()->filter('FirstName', 'Sam');
@@ -188,10 +203,17 @@ This would be equivalent to a SQL query of
188 203
 	:::
189 204
 	... WHERE ("FirstName" NOT IN ('Sam','Sig) OR "Age" NOT IN ('17', '74));
190 205
 
191  
-By default, these filters specify case-insensitive exact matches.  There are a number of suffixes that you can put on 
192  
-field names to change this: `":StartsWith"`, `":EndsWith"`, `":PartialMatch"`, `":GreaterThan"`, `":LessThan"`, `":Negation"`.
  206
+### Search Filter Modifiers
  207
+
  208
+The where clauses showcased in the previous two sections (filter and exclude) specify case-insensitive exact 
  209
+matches by default. However, there are a number of suffixes that you can put on field names to change this 
  210
+behaviour `":StartsWith"`, `":EndsWith"`, `":PartialMatch"`, `":GreaterThan"`, `":LessThan"`, `":Negation"`.
  211
+
  212
+Each of these suffixes is represented in the ORM as a subclass of `[api:SearchFilter]`. Developers can define
  213
+their own SearchFilters if needing to extend the ORM filter and exclude behaviours.
193 214
 
194  
-This query will return everyone whose first name doesn't start with S, who have logged on since 1/1/2011.
  215
+The following is a query which will return everyone whose first name doesn't start with S, who has logged in 
  216
+since 1/1/2011.
195 217
 
196 218
 	:::php
197 219
 	$members = Member::get()->filter(array(
@@ -199,21 +221,14 @@ This query will return everyone whose first name doesn't start with S, who have
199 221
 		'LastVisited:GreaterThan' => '2011-01-01'
200 222
 	));
201 223
 
202  
-If you wish to match against any of a number of columns, you can list several field names, separated by commas.  This 
203  
-will return all members whose first name or surname contain the string 'sam'.
  224
+If you wish to match against any of a number of columns, you can list several field names, separated by commas. 
  225
+This will return all members whose first name or surname contain the string 'sam'.
204 226
 
205 227
 	:::php
206 228
 	$members = Member::get()->filter(array(
207 229
 		'FirstName,Surname:PartialMatch' => 'sam'
208 230
 	));
209 231
 
210  
-If you wish to match against any of a number of values, you can pass an array as the value.  This will return all 
211  
-members whose first name is either Sam or Ingo.
212  
-
213  
-	:::php
214  
-	$members = Member::get()->filter(array(
215  
-		'FirstName' => array('sam', 'ingo'),
216  
-	));
217 232
 
218 233
 ### Subtract
219 234
 
@@ -238,18 +253,20 @@ So far we have only filtered a data list by fields on the object that you're req
238 253
 be okay, but often, a data model is made up of a number of related objects.  For example, in SilverStripe each member 
239 254
 can be placed in a number of groups, and each group has a number of permissions.
240 255
 
241  
-For this, the SilverStripe ORM supports **Relation Filters**.  Any ORM request can be filtered by fields on a related object by 
242  
-specifying the filter key as `<relation-name>.<field-in-related-object>`.  You can chain relations together as many 
243  
-times as is necessary.
  256
+For this, the SilverStripe ORM supports **Relation Filters**.  Any ORM request can be filtered by fields on a related 
  257
+object by specifying the filter key as `<relation-name>.<field-in-related-object>`.  You can chain relations together 
  258
+as many times as is necessary.
244 259
 
245  
-For example, this will return all members assigned ot a group that has a permission record with the code "ADMIN".  In other words, it will return all administrators.
  260
+For example, this will return all members assigned to a group that has a permission record with the code "ADMIN". In 
  261
+other words, it will return all administrators.
246 262
 
247 263
 	:::php
248 264
 	$members = Member::get()->filter(array(
249 265
 		'Groups.Permissions.Code' => 'ADMIN',
250 266
 	));
251 267
 
252  
-Note that we are just joining to these tables to filter the records.  Even if a member is in more than 1 administrator group, unique members will still be returned by this query.
  268
+Note that we are just joining these tables to filter the records. Even if a member is in more than 1 administrator 
  269
+group, unique members will still be returned by this query.
253 270
 
254 271
 The other features of filters can be applied to relation filters as well.  This will return all members in groups whose
255 272
 names start with 'A' or 'B'.
@@ -259,7 +276,8 @@ names start with 'A' or 'B'.
259 276
 		'Groups.Title:StartsWith' => array('A', 'B'),
260 277
 	));
261 278
 
262  
-You can even follow a relation back to the original model class!  This will return all members are in at least 1 group that also has a member called Sam.
  279
+You can even follow a relation back to the original model class!  This will return all members are in at least 1 group 
  280
+that also has a member called Sam.
263 281
 
264 282
 	:::php
265 283
 	$members = Member::get()->filter(array(
@@ -273,13 +291,14 @@ methods that manipulate the SQL query at a lower level.  When using these, pleas
273 291
 are escaped with double quotes, otherwise some DB back-ends (e.g. PostgreSQL) won't work.
274 292
 
275 293
 In general, we advise against using these methods unless it's absolutely necessary.  If the ORM doesn't do quite what 
276  
-you need it to, you may also consider extending the ORM with new data types or filter modifiers (that documentation still needs to be written)
  294
+you need it to, you may also consider extending the ORM with new data types or filter modifiers (that documentation 
  295
+still needs to be written)
277 296
 
278 297
 #### Where clauses
279 298
 
280 299
 You can specify a WHERE clause fragment (that will be combined with other filters using AND) with the `where()` method:
281 300
 
282  
-	:: php
  301
+	:::php
283 302
 	$members = Member::get()->where("\"FirstName\" = 'Sam'")
284 303
 
285 304
 #### Joining 
@@ -292,7 +311,7 @@ You can specify a join with the innerJoin and leftJoin methods.  Both of these m
292 311
 
293 312
 For example:
294 313
 
295  
-	:: php
  314
+	:::php
296 315
 	// Without an alias
297 316
 	$members = Member::get()->leftJoin("Group_Members", "\"Group_Members\".\"MemberID\" = \"Member\".\"ID\"");
298 317
 
@@ -312,7 +331,7 @@ Data is defined in the static variable $db on each class, in the format:
312 331
 
313 332
 	:::php
314 333
 	class Player extends DataObject {
315  
-	  static $db = array(
  334
+	  public static $db = array(
316 335
 	    "FirstName" => "Varchar",
317 336
 	    "Surname" => "Varchar",
318 337
 	    "Description" => "Text",
@@ -331,7 +350,7 @@ default behaviour by making a function called "get`<fieldname>`" or "set`<fieldn
331 350
 
332 351
 	:::php
333 352
 	class Player extends DataObject {
334  
-	  static $db = array(
  353
+	  public static $db = array(
335 354
 	    "Status" => "Enum('Active, Injured, Retired')"
336 355
 	  );
337 356
 	
@@ -379,7 +398,7 @@ new object is created.
379 398
 
380 399
 	:::php
381 400
 	class Player extends DataObject {
382  
-	  static $defaults = array(
  401
+	  public static $defaults = array(
383 402
 	    "Status" => 'Active',
384 403
 	  );
385 404
 	}
@@ -398,7 +417,7 @@ but using the *obj()*-method or accessing through a template will cast the value
398 417
 
399 418
 	:::php
400 419
 	class Player extends DataObject {
401  
-	  static $casting = array(
  420
+	  public static $casting = array(
402 421
 	    "MembershipFee" => 'Currency',
403 422
 	  );
404 423
 	
@@ -423,7 +442,7 @@ on the "Player"-table.
423 442
 	:::php
424 443
 	// access with $myPlayer->Team()
425 444
 	class Player extends DataObject {
426  
-	  static $has_one = array(
  445
+	  public static $has_one = array(
427 446
 	    "Team" => "Team",
428 447
 	  );
429 448
 	}
@@ -434,7 +453,7 @@ parent element in the tree:
434 453
 	:::php
435 454
 	// access with $mySiteTree->Parent()
436 455
 	class SiteTree extends DataObject {
437  
-	  static $has_one = array(
  456
+	  public static $has_one = array(
438 457
 	    "Parent" => "SiteTree",
439 458
 	  );
440 459
 	}
@@ -451,12 +470,12 @@ accessors available on both ends.
451 470
 	:::php
452 471
 	// access with $myTeam->Players() or $player->Team()
453 472
 	class Team extends DataObject {
454  
-	  static $has_many = array(
  473
+	  public static $has_many = array(
455 474
 	    "Players" => "Player",
456 475
 	  );
457 476
 	}
458 477
 	class Player extends DataObject {
459  
-	  static $has_one = array(
  478
+	  public static $has_one = array(
460 479
 	    "Team" => "Team",
461 480
 	  );
462 481
 	}
@@ -465,15 +484,15 @@ accessors available on both ends.
465 484
 To specify multiple $has_manys to the same object you can use dot notation to distinguish them like below
466 485
 
467 486
 	:::php
468  
-	class Person {
469  
-		static $has_many = array(
  487
+	class Person extends DataObject {
  488
+		public static $has_many = array(
470 489
 			"Managing" => "Company.Manager",
471 490
 			"Cleaning" => "Company.Cleaner",
472 491
 		);
473 492
 	}
474 493
 	
475  
-	class Company {
476  
-		static $has_one = array(
  494
+	class Company extends DataObject {
  495
+		public static $has_one = array(
477 496
 			"Manager" => "Person",
478 497
 			"Cleaner" => "Person"
479 498
 		);
@@ -487,12 +506,12 @@ Multiple $has_one relationships are okay if they aren't linking to the same obje
487 506
 	 * THIS IS BAD
488 507
 	 */
489 508
 	class Team extends DataObject {
490  
-	  static $has_many = array(
  509
+	  public static $has_many = array(
491 510
 	    "Players" => "Player",
492 511
 	  );
493 512
 	}
494 513
 	class Player extends DataObject {
495  
-	  static $has_one = array(
  514
+	  public static $has_one = array(
496 515
 	    "Team" => "Team",
497 516
 	    "AnotherTeam" => "Team",
498 517
 	  );
@@ -511,12 +530,12 @@ accessors available on both ends.
511 530
 	:::php
512 531
 	// access with $myTeam->Categories() or $myCategory->Teams()
513 532
 	class Team extends DataObject {
514  
-	  static $many_many = array(
  533
+	  public static $many_many = array(
515 534
 	    "Categories" => "Category",
516 535
 	  );
517 536
 	}
518 537
 	class Category extends DataObject {
519  
-	  static $belongs_many_many = array(
  538
+	  public static $belongs_many_many = array(
520 539
 	    "Teams" => "Team",
521 540
 	  );
522 541
 	}
@@ -524,15 +543,14 @@ accessors available on both ends.
524 543
 
525 544
 ### Adding relations
526 545
 
527  
-Adding new items to a relations works the same,
528  
-regardless if you're editing a *has_many*- or a *many_many*. 
529  
-They are encapsulated by `[api:HasManyList]` and `[api:ManyManyList]`,
530  
-both of which provide very similar APIs, e.g. an `add()` and `remove()` method.
  546
+Adding new items to a relations works the same, regardless if you're editing a *has_many*- or a *many_many*. 
  547
+They are encapsulated by `[api:HasManyList]` and `[api:ManyManyList]`, both of which provide very similar APIs, 
  548
+e.g. an `add()` and `remove()` method.
531 549
 
532 550
 	:::php
533 551
 	class Team extends DataObject {
534 552
 	  // see "many_many"-description for a sample definition of class "Category"
535  
-	  static $many_many = array(
  553
+	  public static $many_many = array(
536 554
 	    "Categories" => "Category",
537 555
 	  );
538 556
 		
@@ -544,13 +562,14 @@ both of which provide very similar APIs, e.g. an `add()` and `remove()` method.
544 562
 
545 563
 ### Custom Relations
546 564
 
547  
-You can use the flexible datamodel to get a filtered result-list without writing any SQL. For example, this snippet gets
548  
-you the "Players"-relation on a team, but only containing active players. 
  565
+You can use the flexible datamodel to get a filtered result-list without writing any SQL. For example, this snippet 
  566
+gets you the "Players"-relation on a team, but only containing active players.
  567
+
549 568
 See `[api:DataObject::$has_many]` for more info on the described relations.
550 569
 
551 570
 	:::php
552 571
 	class Team extends DataObject {
553  
-	  static $has_many = array(
  572
+	  public static $has_many = array(
554 573
 	    "Players" => "Player"
555 574
 	  );
556 575
 	
@@ -560,8 +579,8 @@ See `[api:DataObject::$has_many]` for more info on the described relations.
560 579
 	  }
561 580
 	}
562 581
 
563  
-Note: Adding new records to a filtered `RelationList` like in the example above
564  
-doesn't automatically set the filtered criteria on the added record.
  582
+Note: Adding new records to a filtered `RelationList` like in the example above doesn't automatically set the 
  583
+filtered criteria on the added record.
565 584
 
566 585
 ## Validation and Constraints
567 586
 
@@ -589,10 +608,11 @@ Example: Validate postcodes based on the selected country
589 608
 
590 609
 	:::php
591 610
 	class MyObject extends DataObject {
592  
-		static $db = array(
  611
+		public static $db = array(
593 612
 			'Country' => 'Varchar',
594 613
 			'Postcode' => 'Varchar'
595 614
 		);
  615
+
596 616
 		public function validate() {
597 617
 			$result = parent::validate();
598 618
 			if($this->Country == 'DE' && $this->Postcode && strlen($this->Postcode) != 5) {
@@ -643,7 +663,7 @@ You have to make sure though that certain properties are not overwritten, e.g. *
643 663
 ### Update
644 664
 
645 665
 	:::php
646  
-	$myPlayer = DataObject::get_by_id('Player',99);
  666
+	$myPlayer = Player::get()->byID(99);
647 667
 	if($myPlayer) {
648 668
 	  $myPlayer->Firstname = "John"; // sets property on object
649 669
 	  $myPlayer->write(); // writes row to database
@@ -675,14 +695,15 @@ casting data before saving.
675 695
 
676 696
 ### onBeforeWrite
677 697
 
678  
-You can customize saving-behaviour for each DataObject, e.g. for adding security. These functions are private, obviously
679  
-it wouldn't make sense to call them externally on the object. They are triggered when calling *write()*.
  698
+You can customize saving-behaviour for each DataObject, e.g. for adding workflow or data customization. The function is 
  699
+triggered when calling *write()* to save the object to the database. This includes saving a page in the CMS or altering
  700
+a ModelAdmin record.
680 701
 
681 702
 Example: Disallow creation of new players if the currently logged-in player is not a team-manager.
682 703
 
683 704
 	:::php
684 705
 	class Player extends DataObject {
685  
-	  static $has_many = array(
  706
+	  public static $has_many = array(
686 707
 	    "Teams"=>"Team"
687 708
 	  );
688 709
 	
@@ -722,7 +743,7 @@ It checks if a member is logged in who belongs to a group containing the permiss
722 743
 
723 744
 	:::php
724 745
 	class Player extends DataObject {
725  
-	  static $has_many = array(
  746
+	  public static $has_many = array(
726 747
 	    "Teams"=>"Team"
727 748
 	  );
728 749
 	
@@ -746,19 +767,17 @@ See the ["sql queries" topic](/reference/sqlquery) for custom *INSERT*, *UPDATE*
746 767
 
747 768
 ## Extending DataObjects
748 769
 
749  
-You can add properties and methods to existing `[api:DataObjects]`s like `[api:Member]` (a core class) without hacking core
750  
-code or subclassing.
751  
-Please see `[api:DataExtension]` for a general description, and `[api:Hierarchy]` for our most
752  
-popular examples.
  770
+You can add properties and methods to existing `[api:DataObjects]`s like `[api:Member]` (a core class) without 
  771
+hacking core code or subclassing. See `[api:DataExtension]` for a general description, and `[api:Hierarchy]` for 
  772
+the most popular examples.
753 773
 
754 774
 ## FAQ
755 775
 
756  
-### Whats the difference between DataObject::get() and a relation-getter?
  776
+### What's the difference between DataObject::get() and a relation-getter?
757 777
 
758  
-You can work with both in pretty much the same way, 
759  
-but relationship-getters return a special type of collection: 
  778
+You can work with both in pretty much the same way, but relationship-getters return a special type of collection: 
760 779
 A `[api:HasManyList]` or a `[api:ManyManyList]` with relation-specific functionality.
761 780
 
762 781
 	:::php
763 782
 	$myTeams = $myPlayer->Team(); // returns HasManyList
764  
-	$myTeam->add($myOtherPlayer);
  783
+	$myTeam->add($myOtherPlayer);

0 notes on commit eb82094

Please sign in to comment.
Something went wrong with that request. Please try again.