Skip to content

Commit

Permalink
moved relation classes
Browse files Browse the repository at this point in the history
  • Loading branch information
josephmancuso committed Nov 24, 2024
1 parent 266f696 commit f23adbd
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 91 deletions.
98 changes: 7 additions & 91 deletions playground.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,115 +6,31 @@ class User(Model):

@property
def company(self):
related = Company()

related.owner = self
return HasOne(related, "company_id", "company_id")(self)
return self.has_one(Company, "company_id", "company_id")

class CreditCard(Model):
__table__ = "company_credit_cards"
__primary_key__ = "credit_card_id"

def __call__(self):
return self.__dict__['related'].apply_query(self.builder)

@property
def company(self):
related = Company()
related.owner = self
return HasOne(related, "company_id", "company_id")(self)
return self.has_one(Company, "company_id", "company_id")

class Company(Model):
__table__ = "tbl_companies"
__primary_key__ = "company_id"

def __call__(self):
return self.__dict__['related'].apply_query(self.builder)

@property
def cards(self):
related = CreditCard()
related.owner = self
return HasMany(related, "company_id", "company_id")(self)

class BaseRelationship:
def init(self, model_class, local_key=None, foreign_key=None):
self.model_class = model_class
self.local_key = local_key
self.foreign_key = foreign_key

def __call__(self, owner):
"""Create and return the relationship query."""
# self.set_keys(owner)
related_model = self.model_class()
return self.apply_query(related_model.builder, owner)

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

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

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


def __call__(self, owner):
"""Fetch the related record when invoked."""
related_model = self.model_class
# print("related model", related_model)
related_model.owner = self
foreign_key_value = owner.__attributes__.get(self.foreign_key)
if not foreign_key_value:
return None
builder = related_model.builder.where(self.local_key, foreign_key_value)
result = builder.first()
self.owner = owner
result.__dict__['related'] = self
return result


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

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

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


def __call__(self, owner):
"""Fetch the related record when invoked."""
related_model = self.model_class
# print("related model", related_model)
related_model.owner = self
foreign_key_value = owner.__attributes__.get(self.foreign_key)
if not foreign_key_value:
return None
builder = related_model.builder.where(self.local_key, foreign_key_value)
result = builder.first()
self.owner = owner
result.__dict__['related'] = self
return result

return self.has_many(CreditCard, "company_id", "company_id")

# Usage has one
user = User.find(667)

# fetches record on related company record
print(user.company.cards) # Output: Company name
for card in user.company.cards:
print(card.company.company_name)

# user.company() part returns a query builder so we can fetch related queries on the fly
# print(user.company().limit(1).to_sql()) # Output: select * from tbl_companies where tbl_companies.company_id = 373849
print(user.company().limit(1).to_sql()) # Output: select * from tbl_companies where tbl_companies.company_id = 373849
21 changes: 21 additions & 0 deletions src/masoniteorm/models/Model.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from ..observers import ObservesEvents
from ..query import QueryBuilder
from ..scopes import TimeStampsMixin
from .relationships.new import HasOne, HasMany

"""This is a magic class that will help using models like User.first() instead of having to instatiate a class like
User().first()
Expand Down Expand Up @@ -1175,3 +1176,23 @@ def filter_guarded(cls, dictionary: Dict[str, Any]) -> Dict[str, Any]:
# If all fields are guarded, all data should be filtered
return {}
return {f: dictionary[f] for f in dictionary if f not in cls.__guarded__}

def __call__(self):
return self.__dict__['related'].apply_query(self.builder)


# Move this to a relayion class
def has_one(self, related_model_class, foreign_key=None, local_key=None):
if not local_key:
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 HasOne(related_model_class, foreign_key, local_key)(self)

def has_many(self, related_model_class, foreign_key=None, local_key=None):
if not local_key:
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)

10 changes: 10 additions & 0 deletions src/masoniteorm/models/relationships/new/BaseRelationship.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class BaseRelationship:
def init(self, model_class, local_key=None, foreign_key=None):
self.model_class = model_class
self.local_key = local_key
self.foreign_key = foreign_key

def __call__(self, owner):
"""Create and return the relationship query."""
related_model = self.model_class()
return self.apply_query(related_model.builder, owner)
34 changes: 34 additions & 0 deletions src/masoniteorm/models/relationships/new/HasMany.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from .BaseRelationship import BaseRelationship

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

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

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


def __call__(self, owner):
"""Fetch the related record when invoked."""
related_model = self.model_class
# print("related model", related_model)
related_model.owner = self
self.owner = owner
foreign_key_value = owner.__attributes__.get(self.foreign_key)
if not foreign_key_value:
return None
# builder = related_model.builder.where(self.local_key, foreign_key_value)
builder = self.apply_query(related_model.builder)
result = builder.get()
for item in result:
item.__dict__['related'] = self
self.owner = owner
return result

33 changes: 33 additions & 0 deletions src/masoniteorm/models/relationships/new/HasOne.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from .BaseRelationship import BaseRelationship
class HasOne(BaseRelationship):
"""Belongs To Relationship Class."""

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

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


def __call__(self, owner):
"""Fetch the related record when invoked."""
related_model = self.model_class
# print("related model", related_model)
related_model.owner = self
self.owner = owner
foreign_key_value = owner.__attributes__.get(self.foreign_key)
if not foreign_key_value:
return None
# builder = related_model.builder.where(self.local_key, foreign_key_value)
builder = self.apply_query(related_model.builder)
result = builder.first()
self.owner = owner
result.__dict__['related'] = self
return result

3 changes: 3 additions & 0 deletions src/masoniteorm/models/relationships/new/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .BaseRelationship import BaseRelationship
from .HasOne import HasOne
from .HasMany import HasMany

0 comments on commit f23adbd

Please sign in to comment.