diff --git a/src/Model/Model.php b/src/Model/Model.php index 7c238da..ca85ef0 100644 --- a/src/Model/Model.php +++ b/src/Model/Model.php @@ -568,6 +568,19 @@ public function update(array $attributes = [], array $options = []) return $this->fill($attributes)->save($options); } + /** + * Update the model in the database within a transaction. + * @throws Throwable + */ + public function updateOrFail(array $attributes = [], array $options = []): bool + { + if (! $this->exists) { + return false; + } + + return $this->fill($attributes)->saveOrFail($options); + } + /** * Save the model and all of its relationships. * diff --git a/tests/ModelRealBuilderTest.php b/tests/ModelRealBuilderTest.php index 9bcc952..d23da6a 100644 --- a/tests/ModelRealBuilderTest.php +++ b/tests/ModelRealBuilderTest.php @@ -13,6 +13,7 @@ namespace HyperfTest\Database; use Carbon\Carbon; +use Exception; use Hyperf\Context\ApplicationContext; use Hyperf\Context\Context; use Hyperf\Contract\LengthAwarePaginatorInterface; @@ -24,9 +25,11 @@ use Hyperf\Database\Connectors\ConnectionFactory; use Hyperf\Database\Connectors\MySqlConnector; use Hyperf\Database\Events\QueryExecuted; +use Hyperf\Database\Exception\QueryException; use Hyperf\Database\Model\EnumCollector; use Hyperf\Database\Model\Events\Saved; use Hyperf\Database\Model\Model; +use Hyperf\Database\Model\Register; use Hyperf\Database\MySqlBitConnection; use Hyperf\Database\Query\Builder as QueryBuilder; use Hyperf\Database\Query\Expression; @@ -1279,6 +1282,38 @@ public function testOrderedLazyById(): void Schema::dropIfExists('lazy_users'); } + public function testUpdateOrFail(): void + { + $container = $this->getContainer(); + Register::setConnectionResolver($container->get(ConnectionResolverInterface::class)); + $container->shouldReceive('get')->with(Db::class)->andReturn(new Db($container)); + + Schema::create('update_or_fail', function (Blueprint $table) { + $table->id(); + $table->string('name', 5); + $table->timestamps(); + }); + $model = UpdateOrFail::create([ + 'name' => Str::random(5), + ]); + + try { + $model->updateOrFail([ + 'name' => Str::random(6), + ]); + } catch (Exception $e) { + $this->assertInstanceOf(QueryException::class, $e); + } + + $this->assertFalse((new UpdateOrFail())->updateOrFail([])); + $name = Str::random(4); + $model->updateOrFail([ + 'name' => $name, + ]); + $this->assertSame($name, $model->name); + Schema::drop('update_or_fail'); + } + protected function getContainer() { $dispatcher = Mockery::mock(EventDispatcherInterface::class); @@ -1298,3 +1333,10 @@ class LazyUserModel extends Model { protected ?string $table = 'lazy_users'; } + +class UpdateOrFail extends Model +{ + protected ?string $table = 'update_or_fail'; + + protected array $guarded = []; +}