Skip to content

Commit

Permalink
passed tests
Browse files Browse the repository at this point in the history
  • Loading branch information
josephmancuso committed Nov 25, 2024
1 parent 6c9e9fe commit 1375285
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 10 deletions.
8 changes: 8 additions & 0 deletions src/masoniteorm/collection/Collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class Collection:
def __init__(self, items=None):
self._items = items or []
self.__appends__ = []
self._builder = None

def take(self, number: int):
"""Takes a specific number of results from the items.
Expand Down Expand Up @@ -578,5 +579,12 @@ def __get_items(cls, items):
return items

def __call__(self, *args):
model = self.first()
print('callin collectin. has builder?', self._builder)
if not model and self._builder:
return self._builder

if not model:
return self
related = self._items[0].__dict__['related']
return related.apply_query(self._items[0].builder)
2 changes: 1 addition & 1 deletion src/masoniteorm/models/Model.py
Original file line number Diff line number Diff line change
Expand Up @@ -1197,7 +1197,7 @@ def has_many(self, related_model_class, foreign_key=None, local_key=None):
local_key = f"{related_model_class.get_table_name()}{related_model_class.get_primary_key()}"
if not foreign_key:
foreign_key = related_model_class.get_primary_key()
return HasMany(related_model_class, foreign_key, local_key)(self)
return HasMany(related_model_class, foreign_key, local_key, self._get_calling_property_name())(self)

def _get_calling_property_name(self):
"""Retrieve the name of the property or method that called this."""
Expand Down
22 changes: 16 additions & 6 deletions src/masoniteorm/models/relationships/new/HasMany.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
from .BaseRelationship import BaseRelationship
from ....collection import Collection

class HasMany(BaseRelationship):
"""Belongs To Relationship Class."""

def __init__(self, model_class, foreign_key=None, local_key=None):
def __init__(self, model_class, foreign_key=None, local_key=None, method=None):
self.model_class = model_class
self.foreign_key = foreign_key
self.local_key = local_key
self.method = method
self.owner = None

def apply_query(self, builder, foreign_key_value=None, eager=None):

owner = self.owner
foreign_key_value = owner.__attributes__.get(self.foreign_key)
if not foreign_key_value:
foreign_key_value = owner.__attributes__.get(self.local_key)
return builder.where(self.local_key, foreign_key_value)

def get_related(self, foreign, result, eager=None):
return self.apply_query(self.model_class, getattr(result, self.foreign_key)).first()
return self.apply_query(self.model_class, getattr(result, self.foreign_key)).get()

def __call__(self, owner):
"""Fetch the related record when invoked."""
Expand All @@ -27,12 +30,19 @@ def __call__(self, owner):
foreign_key_value = owner.__attributes__.get(self.foreign_key)
if not foreign_key_value:
return self
builder = self.apply_query(related_model.builder)
result = builder.get()

if self.method and self.method in owner._relationships:
return owner._relationships[self.method]
result = self.apply_query(related_model.builder).get()
result._builder = self.apply_query(self.model_class.builder, foreign_key_value)
for item in result:
item.__dict__['related'] = self
return result

def add_relation(self, model_instance, result, relation_key=None):
# if result is a collection, do a where
return model_instance.add_relation({relation_key: result or []})
print("add relation", model_instance, relation_key, result.count())
result = result or Collection()
result._builder = self.model_class.builder
# print("add relation", model_instance, relation_key, result.count())
return model_instance.add_relation({relation_key: result})
2 changes: 1 addition & 1 deletion src/masoniteorm/query/QueryBuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -1900,7 +1900,6 @@ def prepare_result(self, result, collection=False):
callback = None
print(relation, eagers)
related = getattr(self._model, relation)
# Has one from User -> Profile
result_set = related.get_related(self, hydrated_model)
self._register_relationships_to_model(
related, result_set, hydrated_model, relation_key=relation
Expand All @@ -1917,6 +1916,7 @@ def prepare_result(self, result, collection=False):
related = getattr(self._model, eager)

result_set = related.get_related(self, hydrated_model)
print('rrr', result_set)

self._register_relationships_to_model(
related, result_set, hydrated_model, relation_key=eager
Expand Down
4 changes: 2 additions & 2 deletions tests/models/relationships/test_has_many_relationship.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ def test_can_get_owner_value(self):
user = User.find(1)
self.assertEqual(user.name, "bill")

def test_can_get_has_one_related_value(self):
def test_can_get_has_many_related_value(self):
user = User.find(1)
for article in user.articles:
self.assertEqual(article.title, "masonite")
self.assertEqual(user.articles.first().title, "masonite")

def test_can_get_has_one_query_builder(self):
def test_can_get_has_many_query_builder(self):
user = User.find(1)
self.assertEqual(user.name, "bill")
self.assertEqual(user.articles().to_sql(), 'SELECT * FROM "articles" WHERE "articles"."user_id" = \'1\'')
Expand Down

0 comments on commit 1375285

Please sign in to comment.