Browse Source

Merge pull request #1314 from vFragosop/eloquent/relationship_performance

Huge performance increase on Eloquents relationships
Taylor Otwell 12 years ago
parent
commit
8faf38efe1

+ 8 - 7
laravel/database/eloquent/relationships/belongs_to.php

@@ -87,16 +87,17 @@ class Belongs_To extends Relationship {
 	{
 	{
 		$foreign = $this->foreign_key();
 		$foreign = $this->foreign_key();
 
 
-		foreach ($children as &$child)
+		$parents_hash = array();
+		foreach ($parents as $parent)
 		{
 		{
-			$parent = array_first($parents, function($k, $v) use (&$child, $foreign)
-			{
-				return $v->get_key() == $child->$foreign;
-			});
+			$parents_hash[$parent->get_key()] = $parent;
+		}
 
 
-			if ( ! is_null($parent))
+		foreach ($children as $child)
+		{
+			if (array_key_exists($child->$foreign, $parents_hash))
 			{
 			{
-				$child->relationships[$relationship] = $parent;
+				$child->relationships[$relationship] = $parents_hash[$child->$foreign];
 			}
 			}
 		}
 		}
 	}
 	}

+ 10 - 6
laravel/database/eloquent/relationships/has_many.php

@@ -91,14 +91,18 @@ class Has_Many extends Has_One_Or_Many {
 	{
 	{
 		$foreign = $this->foreign_key();
 		$foreign = $this->foreign_key();
 
 
-		foreach ($parents as &$parent)
+		$children_hash = array();
+		foreach ($children as $child)
 		{
 		{
-			$matching = array_filter($children, function($v) use (&$parent, $foreign)
-			{
-				return $v->$foreign == $parent->get_key();
-			});
+			$children_hash[$child->$foreign][] = $child;
+		}
 
 
-			$parent->relationships[$relationship] = array_values($matching);
+		foreach ($parents as $parent)
+		{
+			if (array_key_exists($parent->get_key(), $children_hash))
+			{
+				$parent->relationships[$relationship] = $children_hash[$parent->get_key()];
+			}
 		}
 		}
 	}
 	}
 
 

+ 10 - 6
laravel/database/eloquent/relationships/has_many_and_belongs_to.php

@@ -328,14 +328,18 @@ class Has_Many_And_Belongs_To extends Relationship {
 	{
 	{
 		$foreign = $this->foreign_key();
 		$foreign = $this->foreign_key();
 
 
-		foreach ($parents as &$parent)
+		$children_hash = array();
+		foreach ($children as $child)
 		{
 		{
-			$matching = array_filter($children, function($v) use (&$parent, $foreign)
-			{
-				return $v->pivot->$foreign == $parent->get_key();
-			});
+			$children_hash[$child->pivot->$foreign][] = $child;
+		}
 
 
-			$parent->relationships[$relationship] = array_values($matching);
+		foreach ($parents as $parent)
+		{
+			if (array_key_exists($parent->get_key(), $children_hash))
+			{
+				$parent->relationships[$relationship] = $children_hash[$parent->get_key()];
+			}
 		}
 		}
 	}
 	}
 
 

+ 12 - 5
laravel/database/eloquent/relationships/has_one.php

@@ -38,14 +38,21 @@ class Has_One extends Has_One_Or_Many {
 	{
 	{
 		$foreign = $this->foreign_key();
 		$foreign = $this->foreign_key();
 
 
-		foreach ($parents as &$parent)
+		$children_hash = array();
+		foreach ($children as $child)
 		{
 		{
-			$matching = array_first($children, function($k, $v) use (&$parent, $foreign)
+			if (array_key_exists($child->pivot->$foreign, $children_hash))
 			{
 			{
-				return $v->$foreign == $parent->get_key();
-			});
+				continue;
+			}
+
+			$children_hash[$child->pivot->$foreign] = $child;
+		}
 
 
-			$parent->relationships[$relationship] = $matching;
+		foreach ($parents as $parent)
+		{
+			if (array_key_exists($parent->get_key(), $children_hash))
+				$parent->relationships[$relationship] = $children_hash[$parent->get_key()];
 		}
 		}
 	}
 	}