Skip to content

Instantly share code, notes, and snippets.

@kkiernan
Last active April 29, 2016 13:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kkiernan/b1014e1b02524f6f64925693d7513a20 to your computer and use it in GitHub Desktop.
Save kkiernan/b1014e1b02524f6f64925693d7513a20 to your computer and use it in GitHub Desktop.
A trait to help deal with handling empty strings in Eloquent models
<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>
<?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);
}
}
<?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