Last active
March 12, 2024 02:30
-
-
Save scrubmx/99f4af42fd66449a8f12013c7a663a12 to your computer and use it in GitHub Desktop.
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\Traits; | |
use LogicException; | |
trait Immutables | |
{ | |
/** | |
* Set a given attribute on the model. | |
* | |
* @override \Illuminate\Database\Eloquent\Model | |
* | |
* @param string $key | |
* @param mixed $value | |
* @return $this | |
* | |
* @throws \LogicException | |
*/ | |
public function setAttribute($key, $value) | |
{ | |
if (! property_exists($this, 'immutables')) { | |
throw new LogicException('Class must define an $immutables array property.'); | |
} | |
// First we will check for the presence of the attribute in the immutables | |
// array property if found then we'll check if a value has already been | |
// set in the model attributes. If both conditions are met just bail. | |
if (in_array($key, $this->immutables) && isset($this->attributes[$key])) { | |
return $this; | |
} | |
return parent::setAttribute($key, $value); | |
} | |
} |
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 Tests\Unit\Models\Traits; | |
use App\Models\Traits\Immutables; | |
use Illuminate\Database\Eloquent\Model; | |
use Illuminate\Support\Carbon; | |
use LogicException; | |
use Tests\TestCase; | |
class ImmutablesTest extends TestCase | |
{ | |
/** @test */ | |
public function it_throws_an_exception_if_immutables_property_is_missing() | |
{ | |
$this->expectException(LogicException::class); | |
$model = new class extends Model { | |
use Immutables; | |
}; | |
$model->year = '2018-01-01 00:00:00'; | |
} | |
/** @test */ | |
public function it_does_not_allow_to_change_a_property_after_it_is_been_set() | |
{ | |
$model = new class extends Model { | |
use Immutables; | |
protected $immutables = ['validated_at']; | |
}; | |
$this->assertNull($model->validated_at); | |
$model->validated_at = '2018-01-01 00:00:00'; | |
$this->assertEquals('2018-01-01 00:00:00', $model->validated_at); | |
$model->validated_at = null; | |
$this->assertNotNull($model->validated_at); | |
$this->assertEquals('2018-01-01 00:00:00', $model->validated_at); | |
} | |
/** @test */ | |
public function it_works_well_with_attribute_mutators() | |
{ | |
$model = new class extends Model { | |
use Immutables; | |
protected $immutables = ['validated_at']; | |
public function setValidatedAtAttribute($value) | |
{ | |
$this->attributes['validated_at'] = Carbon::parse($value)->addYear(); | |
} | |
}; | |
$this->assertNull($model->validated_at); | |
$model->validated_at = '2018-01-01 00:00:00'; | |
$this->assertEquals('2019-01-01 00:00:00', $model->validated_at); | |
$model->validated_at = null; | |
$this->assertEquals('2019-01-01 00:00:00', $model->validated_at); | |
} | |
} |
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; | |
class Subscription extends Model | |
{ | |
use Traits\Immutables; | |
/** | |
* The attributes that should not be mutated once they are set. | |
* | |
* @var array | |
*/ | |
protected $immutables = ['started_at']; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment