diff --git a/fastapi_startkit/src/fastapi_startkit/masoniteorm/models/builder.py b/fastapi_startkit/src/fastapi_startkit/masoniteorm/models/builder.py index 9edfda5c..90b74497 100644 --- a/fastapi_startkit/src/fastapi_startkit/masoniteorm/models/builder.py +++ b/fastapi_startkit/src/fastapi_startkit/masoniteorm/models/builder.py @@ -97,6 +97,14 @@ async def find_or_fail(self, primary_key: str | int, columns=None): ) return result + async def first_or_fail(self, columns=None): + from fastapi_startkit.masoniteorm.exceptions import ModelNotFoundException + + result = await self.first(columns) + if result is None: + raise ModelNotFoundException(f"{self._model.__name__} not found.") + return result + async def first(self, columns=None): if not columns: columns = [] diff --git a/fastapi_startkit/src/fastapi_startkit/masoniteorm/models/model.py b/fastapi_startkit/src/fastapi_startkit/masoniteorm/models/model.py index 98f078f7..ab746cb8 100644 --- a/fastapi_startkit/src/fastapi_startkit/masoniteorm/models/model.py +++ b/fastapi_startkit/src/fastapi_startkit/masoniteorm/models/model.py @@ -107,6 +107,10 @@ async def find(cls, primary_key: str | int, columns=None): async def find_or_fail(cls, primary_key: str | int, columns=None): return await cls.query().find_or_fail(primary_key, columns) + @classmethod + async def first_or_fail(cls, columns=None): + return await cls.query().first_or_fail(columns) + @classmethod async def first(cls, columns=None): return await cls.query().first(columns) diff --git a/fastapi_startkit/tests/masoniteorm/sqlite/models/test_sqlite_model.py b/fastapi_startkit/tests/masoniteorm/sqlite/models/test_sqlite_model.py index facd4be0..e4877688 100644 --- a/fastapi_startkit/tests/masoniteorm/sqlite/models/test_sqlite_model.py +++ b/fastapi_startkit/tests/masoniteorm/sqlite/models/test_sqlite_model.py @@ -65,6 +65,26 @@ async def test_find_or_fail_exception_message_contains_key(self): except ModelNotFoundException as e: self.assertIn("99999", str(e)) + async def test_first_or_fail_returns_model_when_found(self): + user = await User.where("id", 1).first_or_fail() + self.assertIsInstance(user, User) + self.assertEqual(user.id, 1) + + async def test_first_or_fail_raises_when_no_match(self): + with self.assertRaises(ModelNotFoundException): + await User.where("name", "NonExistent").first_or_fail() + + async def test_first_or_fail_exception_has_404_status(self): + try: + await User.where("name", "NonExistent").first_or_fail() + except ModelNotFoundException as e: + self.assertEqual(e.get_status(), 404) + + async def test_first_or_fail_class_method_raises_when_table_empty(self): + await User.query().delete() + with self.assertRaises(ModelNotFoundException): + await User.first_or_fail() + async def test_can_set_and_retrieve_attribute(self): user = await User.first() user.name = "updated"