Browse Source

Fixing update handling in Has_Many and Has_One relationships.

Signed-off-by: Taylor Otwell <taylorotwell@gmail.com>
Taylor Otwell 12 years ago
parent
commit
fda19731c5

+ 3 - 3
laravel/database/eloquent/model.php

@@ -405,7 +405,7 @@ abstract class Model {
 	 */
 	protected function timestamp()
 	{
-		$this->updated_at = $this->get_timestamp();
+		$this->updated_at = static::get_timestamp();
 
 		if ( ! $this->exists) $this->created_at = $this->updated_at;
 	}
@@ -415,7 +415,7 @@ abstract class Model {
 	 *
 	 * @return mixed
 	 */
-	public function get_timestamp()
+	public static function get_timestamp()
 	{
 		return date('Y-m-d H:i:s');
 	}
@@ -675,7 +675,7 @@ abstract class Model {
 	 */
 	public function __call($method, $parameters)
 	{
-		$meta = array('key', 'table', 'connection', 'sequence', 'per_page');
+		$meta = array('key', 'table', 'connection', 'sequence', 'per_page', 'timestamps');
 
 		// If the method is actually the name of a static property on the model we'll
 		// return the value of the static property. This makes it convenient for

+ 7 - 2
laravel/database/eloquent/relationships/has_many.php

@@ -29,8 +29,6 @@ class Has_Many extends Has_One_Or_Many {
 
 		foreach ($models as $attributes)
 		{
-			$attributes[$this->foreign_key()] = $this->base->get_key();
-
 			$class = get_class($this->model);
 
 			// If the "attributes" are actually an array of the related model we'll
@@ -45,6 +43,13 @@ class Has_Many extends Has_One_Or_Many {
 				$model = $this->fresh_model($attributes);
 			}
 
+			// We'll need to associate the model with its parent, so we'll set the
+			// foreign key on the model to the key of the parent model, making
+			// sure that the two models are associated in the database.
+			$foreign = $this->foreign_key();
+
+			$model->$foreign = $this->base->get_key();
+
 			$id = $model->get_key();
 
 			$model->exists = ( ! is_null($id) and in_array($id, $current));

+ 15 - 11
laravel/database/eloquent/relationships/has_many_and_belongs_to.php

@@ -25,7 +25,7 @@ class Has_Many_And_Belongs_To extends Relationship {
 	 *
 	 * @var array
 	 */
-	protected $with = array();
+	protected $with = array('id');
 
 	/**
 	 * Create a new many to many relationship instance.
@@ -43,9 +43,14 @@ class Has_Many_And_Belongs_To extends Relationship {
 
 		$this->joining = $table ?: $this->joining($model, $associated);
 
+		// If the Pivot table is timestamped, we'll set the timestamp columns to be
+		// fetched when the pivot table models are fetched by the developer else
+		// the ID will be the only "extra" column fetched in by default.
 		if (Pivot::$timestamps)
 		{
-			$this->with = array('id', 'created_at', 'updated_at');
+			$this->with[] = 'created_at';
+
+			$this->with[] = 'updated_at';
 		}
 
 		parent::__construct($model, $associated, $foreign);
@@ -197,9 +202,12 @@ class Has_Many_And_Belongs_To extends Relationship {
 	 */
 	protected function insert_joining($attributes)
 	{
-		$attributes['created_at'] = $this->model->get_timestamp();
+		if (Pivot::$timestamps)
+		{
+			$attributes['created_at'] = $this->model->get_timestamp();
 
-		$attributes['updated_at'] = $attributes['created_at'];
+			$attributes['updated_at'] = $attributes['created_at'];
+		}
 
 		return $this->joining_table()->insert($attributes);
 	}
@@ -386,17 +394,13 @@ class Has_Many_And_Belongs_To extends Relationship {
 	}
 
 	/**
-	 * Get a model instance of the pivot table for the relationship.
+	 * Get a relationship instance of the pivot table.
 	 *
-	 * @return Pivot
+	 * @return Has_Many
 	 */
 	public function pivot()
 	{
-		$key = $this->base->get_key();
-
-		$foreign = $this->foreign_key();
-
-		return with(new Pivot($this->joining))->where($foreign, '=', $key);
+		return new Has_Many($this->base, new Pivot($this->joining), $this->foreign_key());
 	}
 
 	/**

+ 16 - 0
laravel/database/eloquent/relationships/has_one_or_many.php

@@ -19,6 +19,22 @@ class Has_One_Or_Many extends Relationship {
 		return $this->model->create($attributes);
 	}
 
+	/**
+	 * Update a record for the association.
+	 *
+	 * @param  array  $attributes
+	 * @return bool
+	 */
+	public function update(array $attributes)
+	{
+		if ($this->model->timestamps())
+		{
+			$attributes['updated_at'] = $this->model->get_timestamp();
+		}
+
+		return $this->table->update($attributes);
+	}
+
 	/**
 	 * Set the proper constraints on the relationship table.
 	 *

+ 2 - 0
laravel/documentation/changes.md

@@ -31,10 +31,12 @@
 - Migrated to the Symfony HttpFoundation component for core request / response handling.
 - Fixed the passing of strings into the Input::except method.
 - Fixed replacement of optional parameters in URL::transpose method.
+- Improved "update" handling on Has_Many and Has_One relationships.
 - Improved View performance by only loading contents from file once.
 - Fix handling of URLs beginning with has in URL::to.
 - Fix the resolution of unset Eloquent attributes.
 - Allows pivot table timestamps to be disabled.
+- Made the "get_timestamp" Eloquent method static.
 
 <a name="upgrade-3.2"></a>
 ## Upgrading From 3.1