laravel/framework — pull request #4555 by jmshelby (2014-06-02 21:23:59+00:00)
Title: Eloquent Pivot - Make sure original attribute values are being set on call to setRawAttributes

This fixes a bug that causes a pivot model to attempt an update call to the database, even though no data has been changed. If my understanding is correct of how this pivot model works, then I believe the intention was to have it track the original data just like any other model.

I also added some unit tests to verify that the original attributes are being tracked on the pivot model.

Example of how to recreate the bug/issue:

```php

// Assume you have a recipe model
// Assume recipe has a many-to-many relationship to categories
// Assume recipe sample has several attached categories via pivot table

// Fetch model
$recipe = Recipe::find(125);

// Fetch many-to-many relationship on model
$recipe->categories;

// Do some other stuff that doesn't end up changing recipe or categories data...

// Call push() on model
$recipe->push();

```

Queries Ran:

```
============================= [QUERY] =========================================
select * from `recipe` where `recipe_id` = 125 limit 1

============================= [QUERY] =========================================
select `category`.*, `category_recipe`.`recipe_id` as `pivot_recipe_id`, `category_recipe`.`category_id` as `pivot_category_id`
from `category` inner join `category_recipe` on `category`.`category_id` = `category_recipe`.`category_id`
where `category_recipe`.`recipe_id` = '125'

============================= [QUERY] =========================================
update `category_recipe`
set `recipe_id` = '125', `category_id` = '1'
where `recipe_id` = '125' and `category_id` = '1'

============================= [QUERY] =========================================
update `category_recipe`
set `recipe_id` = '125', `category_id` = '4'
where `recipe_id` = '125' and `category_id` = '4'

============================= [QUERY] =========================================
update `category_recipe`
set `recipe_id` = '125', `category_id` = '13'
where `recipe_id` = '125' and `category_id` = '13'

============================= [QUERY] =========================================
update `category_recipe`
set `recipe_id` = '125', `category_id` = '82'
where `recipe_id` = '125' and `category_id` = '82'

============================= [QUERY] =========================================
update `category_recipe`
set `recipe_id` = '125', `category_id` = '72'
where `recipe_id` = '125' and `category_id` = '72'

============================= [QUERY] =========================================
update `category_recipe`
set `recipe_id` = '125', `category_id` = '94'
where `recipe_id` = '125' and `category_id` = '94'

```

Obviously the several updates at the end are unnecessarily called; in some cases this could turn out to be a relationship with lots and lots of records.