Last active
April 29, 2016 13:32
-
-
Save kkiernan/b1014e1b02524f6f64925693d7513a20 to your computer and use it in GitHub Desktop.
A trait to help deal with handling empty strings in Eloquent models
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<p>If the $nullableDefault property is set on your model, you will see that value instead of an empty string. For example {{ $product->size }} would show N/A instead of an empty string if the value is null.</p> | |
<p>However, you might not want N/A to show up in a form input, so the original value (null) will be provided if you request the raw value:</p> | |
<form> | |
<input type="text" name="size" value="{{ $product->size_raw }}"> | |
</form> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Models; | |
/** | |
* Converts empty values to nulls before saving a model to storage. | |
*/ | |
trait NullableFields | |
{ | |
/** | |
* Boot the trait. | |
* | |
* @return void | |
*/ | |
public static function bootNullableFields() | |
{ | |
// Register a callback to be triggered when the model is saving that | |
// will unset any nullable fields that are set to empty strings. | |
static::saving(function ($model) { | |
foreach ($model->getNullableFields() as $field) { | |
if ($model->getAttribute($field) === '') { | |
unset($model->{$field}); | |
} | |
} | |
}); | |
} | |
/** | |
* Checks if the given key is replaceable. | |
* | |
* @param string $key | |
* | |
* @return boolean | |
*/ | |
public function fieldIsReplaceable($key) | |
{ | |
// A field is not replaceable if... | |
// ...the nullableDefault property has not been declared. | |
if (!property_exists($this, 'nullableDefault')) { | |
return false; | |
} | |
// ...the given key is not marked as nullable on the model. | |
if (!in_array($key, $this->getNullableFields())) { | |
return false; | |
} | |
// ...it already has a value. | |
if ($this->getAttribute($key) != '') { | |
return false; | |
} | |
// ...the user is requesting the raw value. | |
if (strtolower(substr($key, -3)) == 'raw') { | |
return false; | |
} | |
return true; | |
} | |
/** | |
* Gets the nullable fields. | |
* | |
* @return array | |
*/ | |
public function getNullableFields() | |
{ | |
return $this->nullable; | |
} | |
/** | |
* Gets the nullable default value. | |
* | |
* @return string | |
*/ | |
public function getNullableDefault() | |
{ | |
return $this->nullableDefault; | |
} | |
/** | |
* Dynamically retrieve attributes on the model. | |
* | |
* @param string $key | |
* | |
* @return mixed | |
*/ | |
public function __get($key) | |
{ | |
// Replace an empty nullable value with the nullable default. | |
if ($this->fieldIsReplaceable($key)) { | |
return $this->getNullableDefault(); | |
} | |
// Let Laravel handle the call. | |
return parent::__get($key); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace App\Models; | |
use Illuminate\Database\Eloquent\Model; | |
class Product extends Model | |
{ | |
use NullableFields; | |
/** | |
* @var array | |
*/ | |
protected $fillable = [ | |
'category_id', | |
'name', | |
'brand', | |
'size', | |
'sku', | |
'description', | |
'location', | |
]; | |
/** | |
* @var array | |
*/ | |
protected $nullable = [ | |
'size', | |
'location', | |
]; | |
/** | |
* @var string | |
*/ | |
protected $nullableDefault = 'N/A'; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment