a tiny mvc framework for php using php-activerecord
1<?php
2include 'helpers/config.php';
3
4class NotModel {};
5
6class AuthorWithNonModelRelationship extends ActiveRecord\Model
7{
8 static $pk = 'id';
9 static $table_name = 'authors';
10 static $has_many = array(array('books', 'class_name' => 'NotModel'));
11}
12
13class RelationshipTest extends DatabaseTest
14{
15 protected $relationship_name;
16 protected $relationship_names = array('has_many', 'belongs_to', 'has_one');
17
18 public function set_up($connection_name=null)
19 {
20 parent::set_up($connection_name);
21
22 Event::$belongs_to = array(array('venue'), array('host'));
23 Venue::$has_many = array(array('events', 'order' => 'id asc'),array('hosts', 'through' => 'events', 'order' => 'hosts.id asc'));
24 Venue::$has_one = array();
25 Employee::$has_one = array(array('position'));
26 Host::$has_many = array(array('events', 'order' => 'id asc'));
27
28 foreach ($this->relationship_names as $name)
29 {
30 if (preg_match("/$name/", $this->getName(), $match))
31 $this->relationship_name = $match[0];
32 }
33 }
34
35 protected function get_relationship($type=null)
36 {
37 if (!$type)
38 $type = $this->relationship_name;
39
40 switch ($type)
41 {
42 case 'belongs_to';
43 $ret = Event::find(5);
44 break;
45
46 case 'has_one';
47 $ret = Employee::find(1);
48 break;
49
50 case 'has_many';
51 $ret = Venue::find(2);
52 break;
53 }
54
55 return $ret;
56 }
57
58 protected function assert_default_belongs_to($event, $association_name='venue')
59 {
60 $this->assert_true($event->$association_name instanceof Venue);
61 $this->assert_equals(5,$event->id);
62 $this->assert_equals('West Chester',$event->$association_name->city);
63 $this->assert_equals(6,$event->$association_name->id);
64 }
65
66 protected function assert_default_has_many($venue, $association_name='events')
67 {
68 $this->assert_equals(2,$venue->id);
69 $this->assert_true(count($venue->$association_name) > 1);
70 $this->assert_equals('Yeah Yeah Yeahs',$venue->{$association_name}[0]->title);
71 }
72
73 protected function assert_default_has_one($employee, $association_name='position')
74 {
75 $this->assert_true($employee->$association_name instanceof Position);
76 $this->assert_equals('physicist',$employee->$association_name->title);
77 $this->assert_not_null($employee->id, $employee->$association_name->title);
78 }
79
80 public function test_has_many_basic()
81 {
82 $this->assert_default_has_many($this->get_relationship());
83 }
84
85 /**
86 * @expectedException ActiveRecord\RelationshipException
87 */
88 public function test_joins_on_model_via_undeclared_association()
89 {
90 $x = JoinBook::first(array('joins' => array('undeclared')));
91 }
92
93 public function test_joins_only_loads_given_model_attributes()
94 {
95 $x = Event::first(array('joins' => array('venue')));
96 $this->assert_sql_has('SELECT events.*',Event::table()->last_sql);
97 $this->assert_false(array_key_exists('city', $x->attributes()));
98 }
99
100 public function test_joins_combined_with_select_loads_all_attributes()
101 {
102 $x = Event::first(array('select' => 'events.*, venues.city as venue_city', 'joins' => array('venue')));
103 $this->assert_sql_has('SELECT events.*, venues.city as venue_city',Event::table()->last_sql);
104 $this->assert_true(array_key_exists('venue_city', $x->attributes()));
105 }
106
107 public function test_belongs_to_basic()
108 {
109 $this->assert_default_belongs_to($this->get_relationship());
110 }
111
112 public function test_belongs_to_returns_null_when_no_record()
113 {
114 $event = Event::find(6);
115 $this->assert_null($event->venue);
116 }
117
118 public function test_belongs_to_with_explicit_class_name()
119 {
120 Event::$belongs_to = array(array('explicit_class_name', 'class_name' => 'Venue'));
121 $this->assert_default_belongs_to($this->get_relationship(), 'explicit_class_name');
122 }
123
124 public function test_belongs_to_with_explicit_foreign_key()
125 {
126 $old = Book::$belongs_to;
127 Book::$belongs_to = array(array('explicit_author', 'class_name' => 'Author', 'foreign_key' => 'secondary_author_id'));
128
129 $book = Book::find(1);
130 $this->assert_equals(2, $book->secondary_author_id);
131 $this->assert_equals($book->secondary_author_id, $book->explicit_author->author_id);
132
133 Book::$belongs_to = $old;
134 }
135
136 public function test_belongs_to_with_select()
137 {
138 Event::$belongs_to[0]['select'] = 'id, city';
139 $event = $this->get_relationship();
140 $this->assert_default_belongs_to($event);
141
142 try {
143 $event->venue->name;
144 $this->fail('expected Exception ActiveRecord\UndefinedPropertyException');
145 } catch (ActiveRecord\UndefinedPropertyException $e) {
146 $this->assert_true(strpos($e->getMessage(), 'name') !== false);
147 }
148 }
149
150 public function test_belongs_to_with_readonly()
151 {
152 Event::$belongs_to[0]['readonly'] = true;
153 $event = $this->get_relationship();
154 $this->assert_default_belongs_to($event);
155
156 try {
157 $event->venue->save();
158 $this->fail('expected exception ActiveRecord\ReadonlyException');
159 } catch (ActiveRecord\ReadonlyException $e) {
160 }
161
162 $event->venue->name = 'new name';
163 $this->assert_equals($event->venue->name, 'new name');
164 }
165
166 public function test_belongs_to_with_plural_attribute_name()
167 {
168 Event::$belongs_to = array(array('venues', 'class_name' => 'Venue'));
169 $this->assert_default_belongs_to($this->get_relationship(), 'venues');
170 }
171
172 public function test_belongs_to_with_conditions_and_non_qualifying_record()
173 {
174 Event::$belongs_to[0]['conditions'] = "state = 'NY'";
175 $event = $this->get_relationship();
176 $this->assert_equals(5,$event->id);
177 $this->assert_null($event->venue);
178 }
179
180 public function test_belongs_to_with_conditions_and_qualifying_record()
181 {
182 Event::$belongs_to[0]['conditions'] = "state = 'PA'";
183 $this->assert_default_belongs_to($this->get_relationship());
184 }
185
186 public function test_belongs_to_build_association()
187 {
188 $event = $this->get_relationship();
189 $values = array('city' => 'Richmond', 'state' => 'VA');
190 $venue = $event->build_venue($values);
191 $this->assert_equals($values, array_intersect_key($values, $venue->attributes()));
192 }
193
194 public function test_has_many_build_association()
195 {
196 $author = Author::first();
197 $this->assert_equals($author->id, $author->build_books()->author_id);
198 $this->assert_equals($author->id, $author->build_book()->author_id);
199 }
200
201 public function test_belongs_to_create_association()
202 {
203 $event = $this->get_relationship();
204 $values = array('city' => 'Richmond', 'state' => 'VA', 'name' => 'Club 54', 'address' => '123 street');
205 $venue = $event->create_venue($values);
206 $this->assert_not_null($venue->id);
207 }
208
209 public function test_belongs_to_can_be_self_referential()
210 {
211 Author::$belongs_to = array(array('parent_author', 'class_name' => 'Author', 'foreign_key' => 'parent_author_id'));
212 $author = Author::find(1);
213 $this->assert_equals(1, $author->id);
214 $this->assert_equals(3, $author->parent_author->id);
215 }
216
217 public function test_belongs_to_with_an_invalid_option()
218 {
219 Event::$belongs_to[0]['joins'] = 'venue';
220 $event = Event::first()->venue;
221 $this->assert_sql_doesnt_has('INNER JOIN venues ON(events.venue_id = venues.id)',Event::table()->last_sql);
222 }
223
224 public function test_has_many_with_explicit_class_name()
225 {
226 Venue::$has_many = array(array('explicit_class_name', 'class_name' => 'Event', 'order' => 'id asc'));;
227 $this->assert_default_has_many($this->get_relationship(), 'explicit_class_name');
228 }
229
230 public function test_has_many_with_select()
231 {
232 Venue::$has_many[0]['select'] = 'title, type';
233 $venue = $this->get_relationship();
234 $this->assert_default_has_many($venue);
235
236 try {
237 $venue->events[0]->description;
238 $this->fail('expected Exception ActiveRecord\UndefinedPropertyException');
239 } catch (ActiveRecord\UndefinedPropertyException $e) {
240 $this->assert_true(strpos($e->getMessage(), 'description') !== false);
241 }
242 }
243
244 public function test_has_many_with_readonly()
245 {
246 Venue::$has_many[0]['readonly'] = true;
247 $venue = $this->get_relationship();
248 $this->assert_default_has_many($venue);
249
250 try {
251 $venue->events[0]->save();
252 $this->fail('expected exception ActiveRecord\ReadonlyException');
253 } catch (ActiveRecord\ReadonlyException $e) {
254 }
255
256 $venue->events[0]->description = 'new desc';
257 $this->assert_equals($venue->events[0]->description, 'new desc');
258 }
259
260 public function test_has_many_with_singular_attribute_name()
261 {
262 Venue::$has_many = array(array('event', 'class_name' => 'Event', 'order' => 'id asc'));
263 $this->assert_default_has_many($this->get_relationship(), 'event');
264 }
265
266 public function test_has_many_with_conditions_and_non_qualifying_record()
267 {
268 Venue::$has_many[0]['conditions'] = "title = 'pr0n @ railsconf'";
269 $venue = $this->get_relationship();
270 $this->assert_equals(2,$venue->id);
271 $this->assert_true(empty($venue->events), is_array($venue->events));
272 }
273
274 public function test_has_many_with_conditions_and_qualifying_record()
275 {
276 Venue::$has_many[0]['conditions'] = "title = 'Yeah Yeah Yeahs'";
277 $venue = $this->get_relationship();
278 $this->assert_equals(2,$venue->id);
279 $this->assert_equals($venue->events[0]->title,'Yeah Yeah Yeahs');
280 }
281
282 public function test_has_many_with_sql_clause_options()
283 {
284 Venue::$has_many[0] = array('events',
285 'select' => 'type',
286 'group' => 'type',
287 'limit' => 2,
288 'offset' => 1);
289 Venue::first()->events;
290 $this->assert_sql_has($this->conn->limit("SELECT type FROM events WHERE venue_id=? GROUP BY type",1,2),Event::table()->last_sql);
291 }
292
293 public function test_has_many_through()
294 {
295 $hosts = Venue::find(2)->hosts;
296 $this->assert_equals(2,$hosts[0]->id);
297 $this->assert_equals(3,$hosts[1]->id);
298 }
299
300 public function test_gh27_has_many_through_with_explicit_keys()
301 {
302 $property = Property::first();
303
304 $this->assert_equals(1, $property->amenities[0]->amenity_id);
305 $this->assert_equals(2, $property->amenities[1]->amenity_id);
306 }
307
308 public function test_gh16_has_many_through_inside_a_loop_should_not_cause_an_exception()
309 {
310 $count = 0;
311
312 foreach (Venue::all() as $venue)
313 $count += count($venue->hosts);
314
315 $this->assert_true($count >= 5);
316 }
317
318 /**
319 * @expectedException ActiveRecord\HasManyThroughAssociationException
320 */
321 public function test_has_many_through_no_association()
322 {
323 Event::$belongs_to = array(array('host'));
324 Venue::$has_many[1] = array('hosts', 'through' => 'blahhhhhhh');
325
326 $venue = $this->get_relationship();
327 $n = $venue->hosts;
328 $this->assert_true(count($n) > 0);
329 }
330
331 public function test_has_many_through_with_select()
332 {
333 Event::$belongs_to = array(array('host'));
334 Venue::$has_many[1] = array('hosts', 'through' => 'events', 'select' => 'hosts.*, events.*');
335
336 $venue = $this->get_relationship();
337 $this->assert_true(count($venue->hosts) > 0);
338 $this->assert_not_null($venue->hosts[0]->title);
339 }
340
341 public function test_has_many_through_with_conditions()
342 {
343 Event::$belongs_to = array(array('host'));
344 Venue::$has_many[1] = array('hosts', 'through' => 'events', 'conditions' => array('events.title != ?', 'Love Overboard'));
345
346 $venue = $this->get_relationship();
347 $this->assert_true(count($venue->hosts) === 1);
348 $this->assert_sql_has("events.title !=",ActiveRecord\Table::load('Host')->last_sql);
349 }
350
351 public function test_has_many_through_using_source()
352 {
353 Event::$belongs_to = array(array('host'));
354 Venue::$has_many[1] = array('hostess', 'through' => 'events', 'source' => 'host');
355
356 $venue = $this->get_relationship();
357 $this->assert_true(count($venue->hostess) > 0);
358 }
359
360 /**
361 * @expectedException ReflectionException
362 */
363 public function test_has_many_through_with_invalid_class_name()
364 {
365 Event::$belongs_to = array(array('host'));
366 Venue::$has_one = array(array('invalid_assoc'));
367 Venue::$has_many[1] = array('hosts', 'through' => 'invalid_assoc');
368
369 $this->get_relationship()->hosts;
370 }
371
372 public function test_has_many_with_joins()
373 {
374 $x = Venue::first(array('joins' => array('events')));
375 $this->assert_sql_has('INNER JOIN events ON(venues.id = events.venue_id)',Venue::table()->last_sql);
376 }
377
378 public function test_has_many_with_explicit_keys()
379 {
380 $old = Author::$has_many;
381 Author::$has_many = array(array('explicit_books', 'class_name' => 'Book', 'primary_key' => 'parent_author_id', 'foreign_key' => 'secondary_author_id'));
382 $author = Author::find(4);
383
384 foreach ($author->explicit_books as $book)
385 $this->assert_equals($book->secondary_author_id, $author->parent_author_id);
386
387 $this->assert_true(strpos(ActiveRecord\Table::load('Book')->last_sql, "secondary_author_id") !== false);
388 Author::$has_many = $old;
389 }
390
391 public function test_has_one_basic()
392 {
393 $this->assert_default_has_one($this->get_relationship());
394 }
395
396 public function test_has_one_with_explicit_class_name()
397 {
398 Employee::$has_one = array(array('explicit_class_name', 'class_name' => 'Position'));
399 $this->assert_default_has_one($this->get_relationship(), 'explicit_class_name');
400 }
401
402 public function test_has_one_with_select()
403 {
404 Employee::$has_one[0]['select'] = 'title';
405 $employee = $this->get_relationship();
406 $this->assert_default_has_one($employee);
407
408 try {
409 $employee->position->active;
410 $this->fail('expected Exception ActiveRecord\UndefinedPropertyException');
411 } catch (ActiveRecord\UndefinedPropertyException $e) {
412 $this->assert_true(strpos($e->getMessage(), 'active') !== false);
413 }
414 }
415
416 public function test_has_one_with_order()
417 {
418 Employee::$has_one[0]['order'] = 'title';
419 $employee = $this->get_relationship();
420 $this->assert_default_has_one($employee);
421 $this->assert_sql_has('ORDER BY title',Position::table()->last_sql);
422 }
423
424 public function test_has_one_with_conditions_and_non_qualifying_record()
425 {
426 Employee::$has_one[0]['conditions'] = "title = 'programmer'";
427 $employee = $this->get_relationship();
428 $this->assert_equals(1,$employee->id);
429 $this->assert_null($employee->position);
430 }
431
432 public function test_has_one_with_conditions_and_qualifying_record()
433 {
434 Employee::$has_one[0]['conditions'] = "title = 'physicist'";
435 $this->assert_default_has_one($this->get_relationship());
436 }
437
438 public function test_has_one_with_readonly()
439 {
440 Employee::$has_one[0]['readonly'] = true;
441 $employee = $this->get_relationship();
442 $this->assert_default_has_one($employee);
443
444 try {
445 $employee->position->save();
446 $this->fail('expected exception ActiveRecord\ReadonlyException');
447 } catch (ActiveRecord\ReadonlyException $e) {
448 }
449
450 $employee->position->title = 'new title';
451 $this->assert_equals($employee->position->title, 'new title');
452 }
453
454 public function test_has_one_can_be_self_referential()
455 {
456 Author::$has_one[1] = array('parent_author', 'class_name' => 'Author', 'foreign_key' => 'parent_author_id');
457 $author = Author::find(1);
458 $this->assert_equals(1, $author->id);
459 $this->assert_equals(3, $author->parent_author->id);
460 }
461
462 public function test_has_one_with_joins()
463 {
464 $x = Employee::first(array('joins' => array('position')));
465 $this->assert_sql_has('INNER JOIN positions ON(employees.id = positions.employee_id)',Employee::table()->last_sql);
466 }
467
468 public function test_has_one_with_explicit_keys()
469 {
470 Book::$has_one = array(array('explicit_author', 'class_name' => 'Author', 'foreign_key' => 'parent_author_id', 'primary_key' => 'secondary_author_id'));
471
472 $book = Book::find(1);
473 $this->assert_equals($book->secondary_author_id, $book->explicit_author->parent_author_id);
474 $this->assert_true(strpos(ActiveRecord\Table::load('Author')->last_sql, "parent_author_id") !== false);
475 }
476
477 public function test_dont_attempt_to_load_if_all_foreign_keys_are_null()
478 {
479 $event = new Event();
480 $event->venue;
481 $this->assert_sql_doesnt_has($this->conn->last_query,'is IS NULL');
482 }
483
484 public function test_relationship_on_table_with_underscores()
485 {
486 $this->assert_equals(1,Author::find(1)->awesome_person->is_awesome);
487 }
488
489 public function test_has_one_through()
490 {
491 Venue::$has_many = array(array('events'),array('hosts', 'through' => 'events'));
492 $venue = Venue::first();
493 $this->assert_true(count($venue->hosts) > 0);
494 }
495
496 /**
497 * @expectedException ActiveRecord\RelationshipException
498 */
499 public function test_throw_error_if_relationship_is_not_a_model()
500 {
501 AuthorWithNonModelRelationship::first()->books;
502 }
503
504 public function test_gh93_and_gh100_eager_loading_respects_association_options()
505 {
506 Venue::$has_many = array(array('events', 'class_name' => 'Event', 'order' => 'id asc', 'conditions' => array('length(title) = ?', 14)));
507 $venues = Venue::find(array(2, 6), array('include' => 'events'));
508
509 $this->assert_sql_has("WHERE length(title) = ? AND venue_id IN(?,?) ORDER BY id asc",ActiveRecord\Table::load('Event')->last_sql);
510 $this->assert_equals(1, count($venues[0]->events));
511 }
512
513 public function test_eager_loading_has_many_x()
514 {
515 $venues = Venue::find(array(2, 6), array('include' => 'events'));
516 $this->assert_sql_has("WHERE venue_id IN(?,?)",ActiveRecord\Table::load('Event')->last_sql);
517
518 foreach ($venues[0]->events as $event)
519 $this->assert_equals($event->venue_id, $venues[0]->id);
520
521 $this->assert_equals(2, count($venues[0]->events));
522 }
523
524 public function test_eager_loading_has_many_with_no_related_rows()
525 {
526 $venues = Venue::find(array(7, 8), array('include' => 'events'));
527
528 foreach ($venues as $v)
529 $this->assert_true(empty($v->events));
530
531 $this->assert_sql_has("WHERE id IN(?,?)",ActiveRecord\Table::load('Venue')->last_sql);
532 $this->assert_sql_has("WHERE venue_id IN(?,?)",ActiveRecord\Table::load('Event')->last_sql);
533 }
534
535 public function test_eager_loading_has_many_array_of_includes()
536 {
537 Author::$has_many = array(array('books'), array('awesome_people'));
538 $authors = Author::find(array(1,2), array('include' => array('books', 'awesome_people')));
539
540 $assocs = array('books', 'awesome_people');
541
542 foreach ($assocs as $assoc)
543 {
544 $this->assert_type('array', $authors[0]->$assoc);
545
546 foreach ($authors[0]->$assoc as $a)
547 $this->assert_equals($authors[0]->author_id,$a->author_id);
548 }
549
550 foreach ($assocs as $assoc)
551 {
552 $this->assert_type('array', $authors[1]->$assoc);
553 $this->assert_true(empty($authors[1]->$assoc));
554 }
555
556 $this->assert_sql_has("WHERE author_id IN(?,?)",ActiveRecord\Table::load('Author')->last_sql);
557 $this->assert_sql_has("WHERE author_id IN(?,?)",ActiveRecord\Table::load('Book')->last_sql);
558 $this->assert_sql_has("WHERE author_id IN(?,?)",ActiveRecord\Table::load('AwesomePerson')->last_sql);
559 }
560
561 public function test_eager_loading_has_many_nested()
562 {
563 $venues = Venue::find(array(1,2), array('include' => array('events' => array('host'))));
564
565 $this->assert_equals(2, count($venues));
566
567 foreach ($venues as $v)
568 {
569 $this->assert_true(count($v->events) > 0);
570
571 foreach ($v->events as $e)
572 {
573 $this->assert_equals($e->host_id, $e->host->id);
574 $this->assert_equals($v->id, $e->venue_id);
575 }
576 }
577
578 $this->assert_sql_has("WHERE id IN(?,?)",ActiveRecord\Table::load('Venue')->last_sql);
579 $this->assert_sql_has("WHERE venue_id IN(?,?)",ActiveRecord\Table::load('Event')->last_sql);
580 $this->assert_sql_has("WHERE id IN(?,?,?)",ActiveRecord\Table::load('Host')->last_sql);
581 }
582
583 public function test_eager_loading_belongs_to()
584 {
585 $events = Event::find(array(1,2,3,5,7), array('include' => 'venue'));
586
587 foreach ($events as $event)
588 $this->assert_equals($event->venue_id, $event->venue->id);
589
590 $this->assert_sql_has("WHERE id IN(?,?,?,?,?)",ActiveRecord\Table::load('Venue')->last_sql);
591 }
592
593 public function test_eager_loading_belongs_to_array_of_includes()
594 {
595 $events = Event::find(array(1,2,3,5,7), array('include' => array('venue', 'host')));
596
597 foreach ($events as $event)
598 {
599 $this->assert_equals($event->venue_id, $event->venue->id);
600 $this->assert_equals($event->host_id, $event->host->id);
601 }
602
603 $this->assert_sql_has("WHERE id IN(?,?,?,?,?)",ActiveRecord\Table::load('Event')->last_sql);
604 $this->assert_sql_has("WHERE id IN(?,?,?,?,?)",ActiveRecord\Table::load('Host')->last_sql);
605 $this->assert_sql_has("WHERE id IN(?,?,?,?,?)",ActiveRecord\Table::load('Venue')->last_sql);
606 }
607
608 public function test_eager_loading_belongs_to_nested()
609 {
610 Author::$has_many = array(array('awesome_people'));
611
612 $books = Book::find(array(1,2), array('include' => array('author' => array('awesome_people'))));
613
614 $assocs = array('author', 'awesome_people');
615
616 foreach ($books as $book)
617 {
618 $this->assert_equals($book->author_id,$book->author->author_id);
619 $this->assert_equals($book->author->author_id,$book->author->awesome_people[0]->author_id);
620 }
621
622 $this->assert_sql_has("WHERE book_id IN(?,?)",ActiveRecord\Table::load('Book')->last_sql);
623 $this->assert_sql_has("WHERE author_id IN(?,?)",ActiveRecord\Table::load('Author')->last_sql);
624 $this->assert_sql_has("WHERE author_id IN(?,?)",ActiveRecord\Table::load('AwesomePerson')->last_sql);
625 }
626
627 public function test_eager_loading_belongs_to_with_no_related_rows()
628 {
629 $e1 = Event::create(array('venue_id' => 200, 'host_id' => 200, 'title' => 'blah','type' => 'Music'));
630 $e2 = Event::create(array('venue_id' => 200, 'host_id' => 200, 'title' => 'blah2','type' => 'Music'));
631
632 $events = Event::find(array($e1->id, $e2->id), array('include' => 'venue'));
633
634 foreach ($events as $e)
635 $this->assert_null($e->venue);
636
637 $this->assert_sql_has("WHERE id IN(?,?)",ActiveRecord\Table::load('Event')->last_sql);
638 $this->assert_sql_has("WHERE id IN(?,?)",ActiveRecord\Table::load('Venue')->last_sql);
639 }
640
641 public function test_eager_loading_clones_related_objects()
642 {
643 $events = Event::find(array(2,3), array('include' => array('venue')));
644
645 $venue = $events[0]->venue;
646 $venue->name = "new name";
647
648 $this->assert_equals($venue->id, $events[1]->venue->id);
649 $this->assert_not_equals($venue->name, $events[1]->venue->name);
650 $this->assert_not_equals(spl_object_hash($venue), spl_object_hash($events[1]->venue));
651 }
652
653 public function test_eager_loading_clones_nested_related_objects()
654 {
655 $venues = Venue::find(array(1,2,6,9), array('include' => array('events' => array('host'))));
656
657 $unchanged_host = $venues[2]->events[0]->host;
658 $changed_host = $venues[3]->events[0]->host;
659 $changed_host->name = "changed";
660
661 $this->assert_equals($changed_host->id, $unchanged_host->id);
662 $this->assert_not_equals($changed_host->name, $unchanged_host->name);
663 $this->assert_not_equals(spl_object_hash($changed_host), spl_object_hash($unchanged_host));
664 }
665
666 public function test_gh_23_relationships_with_joins_to_same_table_should_alias_table_name()
667 {
668 $old = Book::$belongs_to;
669 Book::$belongs_to = array(
670 array('from_', 'class_name' => 'Author', 'foreign_key' => 'author_id'),
671 array('to', 'class_name' => 'Author', 'foreign_key' => 'secondary_author_id'),
672 array('another', 'class_name' => 'Author', 'foreign_key' => 'secondary_author_id')
673 );
674
675 $c = ActiveRecord\Table::load('Book')->conn;
676
677 $select = "books.*, authors.name as to_author_name, {$c->quote_name('from_')}.name as from_author_name, {$c->quote_name('another')}.name as another_author_name";
678 $book = Book::find(2, array('joins' => array('to', 'from_', 'another'),
679 'select' => $select));
680
681 $this->assert_not_null($book->from_author_name);
682 $this->assert_not_null($book->to_author_name);
683 $this->assert_not_null($book->another_author_name);
684 Book::$belongs_to = $old;
685 }
686
687 public function test_gh_40_relationships_with_joins_aliases_table_name_in_conditions()
688 {
689 $event = Event::find(1, array('joins' => array('venue')));
690
691 $this->assert_equals($event->id, $event->venue->id);
692 }
693
694 /**
695 * @expectedException ActiveRecord\RecordNotFound
696 */
697 public function test_dont_attempt_eager_load_when_record_does_not_exist()
698 {
699 Author::find(999999, array('include' => array('books')));
700 }
701};
702?>