From fda19731c5ff33cdc986b2b6635bf9f135ccd06b Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Tue, 10 Apr 2012 11:26:03 -0500 Subject: [PATCH] Fixing update handling in Has_Many and Has_One relationships. Signed-off-by: Taylor Otwell --- laravel/database/eloquent/model.php | 6 ++--- .../eloquent/relationships/has_many.php | 9 +++++-- .../relationships/has_many_and_belongs_to.php | 26 +++++++++++-------- .../relationships/has_one_or_many.php | 16 ++++++++++++ laravel/documentation/changes.md | 2 ++ 5 files changed, 43 insertions(+), 16 deletions(-) diff --git a/laravel/database/eloquent/model.php b/laravel/database/eloquent/model.php index 2f565e57..0bfeec77 100644 --- a/laravel/database/eloquent/model.php +++ b/laravel/database/eloquent/model.php @@ -405,7 +405,7 @@ public function delete() */ 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 @@ protected function timestamp() * * @return mixed */ - public function get_timestamp() + public static function get_timestamp() { return date('Y-m-d H:i:s'); } @@ -675,7 +675,7 @@ public function __unset($key) */ 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 diff --git a/laravel/database/eloquent/relationships/has_many.php b/laravel/database/eloquent/relationships/has_many.php index cbf216e7..d14652a4 100644 --- a/laravel/database/eloquent/relationships/has_many.php +++ b/laravel/database/eloquent/relationships/has_many.php @@ -29,8 +29,6 @@ public function save($models) 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 @@ public function save($models) $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)); diff --git a/laravel/database/eloquent/relationships/has_many_and_belongs_to.php b/laravel/database/eloquent/relationships/has_many_and_belongs_to.php index 628e3a8f..b7b4dbb7 100644 --- a/laravel/database/eloquent/relationships/has_many_and_belongs_to.php +++ b/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 @@ public function __construct($model, $associated, $table, $foreign, $other) $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 @@ protected function join_record($id) */ 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 @@ public function with($columns) } /** - * 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()); } /** diff --git a/laravel/database/eloquent/relationships/has_one_or_many.php b/laravel/database/eloquent/relationships/has_one_or_many.php index 2cdac83e..9df2fb05 100644 --- a/laravel/database/eloquent/relationships/has_one_or_many.php +++ b/laravel/database/eloquent/relationships/has_one_or_many.php @@ -19,6 +19,22 @@ public function insert($attributes) 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. * diff --git a/laravel/documentation/changes.md b/laravel/documentation/changes.md index 123dbb13..f7817d5e 100644 --- a/laravel/documentation/changes.md +++ b/laravel/documentation/changes.md @@ -31,10 +31,12 @@ ## Laravel 3.2 - 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. ## Upgrading From 3.1