generated from MasoniteFramework/starter-package
-
-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5da7c38
commit 723d409
Showing
11 changed files
with
311 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
class Database: | ||
""" | ||
Simulate a database query. Replace this with actual database calls. | ||
""" | ||
@staticmethod | ||
def get(table, conditions): | ||
# Dummy data for demonstration | ||
data = { | ||
"companies": [{"company_id": 1, "name": "Acme Corp"}], | ||
"users": [{"user_id": 1, "company_id": 1, "name": "John Doe"}], | ||
} | ||
return data['companies'][0] | ||
|
||
|
||
class HasOne: | ||
def __init__(self, parent, related_model, foreign_key, local_key): | ||
self.parent = parent | ||
self.related_model = related_model | ||
self.foreign_key = foreign_key | ||
self.local_key = local_key | ||
self._related_instance = None | ||
|
||
def get(self): | ||
""" | ||
Perform the database query to fetch the related model. | ||
""" | ||
if self._related_instance is None: | ||
related_data = Database.get( | ||
self.related_model.table_name(), | ||
{self.foreign_key: getattr(self.parent, self.local_key)} | ||
) | ||
if related_data: | ||
self._related_instance = self.related_model(**related_data) | ||
return self._related_instance | ||
|
||
def __call__(self): | ||
""" | ||
Allow the relationship instance to be callable. | ||
""" | ||
return self | ||
|
||
|
||
class RelationshipProperty: | ||
""" | ||
A wrapper for dual behavior: as a property and as a callable returning the relationship instance. | ||
""" | ||
def __init__(self, relationship): | ||
self.relationship = relationship | ||
|
||
def __getattr__(self, name): | ||
""" | ||
Delegate attribute access to the related model instance. | ||
""" | ||
print("Delegating attribute access to the related model instance") | ||
related_instance = self.relationship.get() | ||
if related_instance: | ||
return getattr(related_instance, name) | ||
raise AttributeError(f"{self.__class__.__name__} has no attribute '{name}'") | ||
|
||
def __call__(self): | ||
""" | ||
Make the relationship callable to return the relationship instance. | ||
""" | ||
return self.relationship | ||
|
||
def __repr__(self): | ||
return repr(self.relationship.get()) | ||
|
||
|
||
|
||
|
||
class Model: | ||
""" | ||
Base model class to share common functionality. | ||
""" | ||
@classmethod | ||
def table_name(cls): | ||
return cls.__name__.lower() + "s" # Example: User -> users | ||
|
||
def has_one(self, related_model, foreign_key=None, local_key="id"): | ||
return RelationshipProperty(HasOne(self, related_model, foreign_key, local_key)) | ||
|
||
|
||
class Company(Model): | ||
def __init__(self, company_id, name): | ||
self.company_id = company_id | ||
self.name = name | ||
|
||
def welcome(self): | ||
return f"Welcome to {self.name}" | ||
|
||
class User(Model): | ||
def __init__(self, user_id, company_id, name): | ||
self.user_id = user_id | ||
self.company_id = company_id | ||
self.name = name | ||
|
||
@property | ||
def company(self): | ||
""" | ||
Return a RelationshipProperty wrapper for dual behavior. | ||
""" | ||
return self.has_one(Company, "company_id", "company_id") | ||
|
||
|
||
# Usage | ||
user = User(user_id=1, company_id=1, name="John Doe") | ||
|
||
# Access the related company instance as a property | ||
related_company = user.company | ||
print("property", related_company) # Output: Acme Corp | ||
print("property", related_company.name, related_company.name=="Acme Corp") # Output: Acme Corp | ||
|
||
# Call the relationship instance to get the related company | ||
related_company_callable = user.company() | ||
print("callable", isinstance(related_company_callable, HasOne)) # Output: True |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
from src.masoniteorm.query import QueryBuilder | ||
from src.masoniteorm.models import Model | ||
from src.masoniteorm.models.relationships import HasOne | ||
|
||
|
||
class CreditCard(Model): | ||
__table__ = "company_credit_cards" | ||
__primary_key__ = "credit_card_id" | ||
|
||
|
||
class Company(Model): | ||
__table__ = "tbl_companies" | ||
|
||
@property | ||
def cards(self): | ||
""" | ||
Return a RelationshipProperty wrapper for dual behavior. | ||
""" | ||
return self.has_many(CreditCard, "company_id", "company_id") | ||
|
||
class User(Model): | ||
__table__ = "tbl_users" | ||
__primary_key__ = "user_id" | ||
|
||
@property | ||
def company(self): | ||
""" | ||
Return a RelationshipProperty wrapper for dual behavior. | ||
""" | ||
return self.has_one(Company, "company_id", "company_id") | ||
|
||
|
||
# Usage | ||
# user = User(user_id=1, company_id=1, name="John Doe") | ||
user = User.find(667) | ||
|
||
# Access the related company instance as a property | ||
# related_company = user.company | ||
# print("property name", related_company.company_name) # Output: Acme Corp | ||
# print("property 2", related_company.company_name, related_company.company_name=="Acme Corp") # Output: Acme Corp | ||
|
||
# # Call the relationship instance to get the related company | ||
# related_company_callable = user.company().get() | ||
company = user.company | ||
print(company.cards().to_sql()) | ||
# print("callable", isinstance(user.company(), HasOne)) # Output: True | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
from .Model import Model | ||
from .Model import Model |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
class HasOne: | ||
def __init__(self, parent, related_model, foreign_key, local_key): | ||
self.parent = parent | ||
self.related_model = related_model | ||
self.foreign_key = foreign_key | ||
self.local_key = local_key | ||
self._related_instance = None | ||
|
||
def get(self): | ||
""" | ||
Perform the database query to fetch the related model. | ||
""" | ||
print("getting") | ||
if self._related_instance is None: | ||
self._related_instance = self.related_model.where(self.foreign_key, getattr(self.parent, self.foreign_key)).first() | ||
|
||
return self._related_instance | ||
|
||
def __call__(self): | ||
""" | ||
Allow the relationship instance to be callable. | ||
""" | ||
print("calling") | ||
return self | ||
|
||
def where(self, key, value): | ||
return self.related_model.where(key, value) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
from .HasOne import HasOne |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
class HasMany: | ||
def __init__(self, parent, related_model, foreign_key, local_key): | ||
self.parent = parent | ||
self.related_model = related_model | ||
self.foreign_key = foreign_key | ||
self.local_key = local_key | ||
self._related_instance = None | ||
|
||
def get(self): | ||
""" | ||
Perform the database query to fetch the related model. | ||
""" | ||
print("getting has many") | ||
if self._related_instance is None: | ||
self._related_instance = self.apply_query().get() | ||
|
||
return self._related_instance | ||
|
||
def __call__(self): | ||
""" | ||
Allow the relationship instance to be callable. | ||
""" | ||
print("calling") | ||
return self.relationship.apply_query().get() | ||
|
||
def where(self, key): | ||
return self.related_model.where(key, value) | ||
|
||
def apply_query(self): | ||
"""Apply the query and return a dictionary to be hydrated | ||
Arguments: | ||
foreign {oject} -- The relationship object | ||
owner {object} -- The current model oject. | ||
Returns: | ||
dict -- A dictionary of data which will be hydrated. | ||
""" | ||
print("applying query has many") | ||
return self.related_model.where(self.foreign_key, getattr(self.parent, self.foreign_key)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
class HasOne: | ||
def __init__(self, parent, related_model, foreign_key, local_key): | ||
self.parent = parent | ||
self.related_model = related_model | ||
self.foreign_key = foreign_key | ||
self.local_key = local_key | ||
self._related_instance = None | ||
|
||
def get(self): | ||
""" | ||
Perform the database query to fetch the related model. | ||
""" | ||
if self._related_instance is None: | ||
self._related_instance = self.apply_query().first() | ||
|
||
return self._related_instance | ||
|
||
def __call__(self): | ||
""" | ||
Allow the relationship instance to be callable. | ||
""" | ||
return self | ||
|
||
def __repr__(self): | ||
return repr(self.related_model) | ||
|
||
def where(self, key): | ||
return self.related_model.where(key, value) | ||
|
||
def apply_query(self): | ||
"""Apply the query and return a dictionary to be hydrated | ||
Arguments: | ||
foreign {oject} -- The relationship object | ||
owner {object} -- The current model oject. | ||
Returns: | ||
dict -- A dictionary of data which will be hydrated. | ||
""" | ||
|
||
return self.related_model.where(self.foreign_key, getattr(self.parent, self.foreign_key)) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from .HasOne import HasOne | ||
from .HasMany import HasMany | ||
# from .BelongsTo import BelongsTo |