Project-Props/Props — pull request #16 by davidpdrsn (2014-05-10 19:47:23+00:00)
Title: Refactor model save

Hi there :smile:

I think I'm done refactoring the Model save method for now. Its become considerably shorter and should hopefully be easier to maintain in the future. As you'll see its still quite long but I didn't see any obvious ways to make it shorter without making it less understandable.

Here is a very comment version of the code that will hopefully give you an understanding of whats going on.

I have tried not to explain what the code does (you will learn that by reading the code) but rather what my intention of the code is.

```php
datetime();

// if the record has not saved to the database yet we have to use INSERT INTO otherwise we
// have to use UPDATE
if ($this->new_record()) {
$this->id = $this->next_insert_id();

if ($this->has_timestamps()) {
$this->date_added = $date;
$this->date_updated = $date;
}

// the $this->sql_columns_and_values() method will return an associative array (hash map)
// where the keys are the names of columns in the objects table
// and the values are what the value of that column should be
// is method is cool because it remove duplication between the insert and update
// branches of this method

// $columns will be something like "id, name, description..."
$columns = join(", ", array_keys($this->sql_columns_and_values()));

// $values will be something like "NULL, 'en stol', 'en fin stol'..."
$values = join(", ", array_values($this->sql_columns_and_values()));

$sql = "INSERT INTO ". static::TABLE_NAME ." (". $columns .") VALUES (". $values .")";
} else {
if ($this->has_timestamps()) {
$this->date_updated = $date;
}

$assigns = [];

foreach ($this->sql_columns_and_values() as $key => $value) {
array_push($assigns, "$key = $value");
}

// $assigns will be something like "id = 10, name = 'en stol'..."

$sql = "UPDATE ". static::TABLE_NAME ." SET ". join(", ", $assigns) ." WHERE id = " . $this->id;
}

static::db()->query($sql);
}

// code is here...
}
```

Would be cool if you would pull down this branch and try to run the tests and look a little at the code to see if it makes sense to you. If you have any ideas of how to improve it and make it more clear and easier to read, please speak up :)