Skip to content

Commit d28d65c

Browse files
authored
Merge pull request #61 from fastapi-startkit/feat/first-or-fail
feat: add first_or_fail to QueryBuilder and Model
2 parents 569270e + 7410fbe commit d28d65c

3 files changed

Lines changed: 32 additions & 0 deletions

File tree

fastapi_startkit/src/fastapi_startkit/masoniteorm/models/builder.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,14 @@ async def find_or_fail(self, primary_key: str | int, columns=None):
9797
)
9898
return result
9999

100+
async def first_or_fail(self, columns=None):
101+
from fastapi_startkit.masoniteorm.exceptions import ModelNotFoundException
102+
103+
result = await self.first(columns)
104+
if result is None:
105+
raise ModelNotFoundException(f"{self._model.__name__} not found.")
106+
return result
107+
100108
async def first(self, columns=None):
101109
if not columns:
102110
columns = []

fastapi_startkit/src/fastapi_startkit/masoniteorm/models/model.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ async def find(cls, primary_key: str | int, columns=None):
107107
async def find_or_fail(cls, primary_key: str | int, columns=None):
108108
return await cls.query().find_or_fail(primary_key, columns)
109109

110+
@classmethod
111+
async def first_or_fail(cls, columns=None):
112+
return await cls.query().first_or_fail(columns)
113+
110114
@classmethod
111115
async def first(cls, columns=None):
112116
return await cls.query().first(columns)

fastapi_startkit/tests/masoniteorm/sqlite/models/test_sqlite_model.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,26 @@ async def test_find_or_fail_exception_message_contains_key(self):
6565
except ModelNotFoundException as e:
6666
self.assertIn("99999", str(e))
6767

68+
async def test_first_or_fail_returns_model_when_found(self):
69+
user = await User.where("id", 1).first_or_fail()
70+
self.assertIsInstance(user, User)
71+
self.assertEqual(user.id, 1)
72+
73+
async def test_first_or_fail_raises_when_no_match(self):
74+
with self.assertRaises(ModelNotFoundException):
75+
await User.where("name", "NonExistent").first_or_fail()
76+
77+
async def test_first_or_fail_exception_has_404_status(self):
78+
try:
79+
await User.where("name", "NonExistent").first_or_fail()
80+
except ModelNotFoundException as e:
81+
self.assertEqual(e.get_status(), 404)
82+
83+
async def test_first_or_fail_class_method_raises_when_table_empty(self):
84+
await User.query().delete()
85+
with self.assertRaises(ModelNotFoundException):
86+
await User.first_or_fail()
87+
6888
async def test_can_set_and_retrieve_attribute(self):
6989
user = await User.first()
7090
user.name = "updated"

0 commit comments

Comments
 (0)