Skip to content

Add nested relationship handling and new models for logos and articles #943

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: 2.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/pythonapp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on: [push, pull_request]

jobs:
build:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04

services:
postgres:
Expand All @@ -30,7 +30,7 @@ jobs:

strategy:
matrix:
python-version: ["3.6", "3.7", "3.8", "3.9"]
python-version: ["3.7", "3.8", "3.9"]
name: Python ${{ matrix.python-version }}
steps:
- uses: actions/checkout@v1
Expand Down Expand Up @@ -58,14 +58,14 @@ jobs:
python orm migrate --connection mysql
make test
lint:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
name: Lint
steps:
- uses: actions/checkout@v1
- name: Set up Python 3.6
- name: Set up Python 3.7
uses: actions/setup-python@v4
with:
python-version: 3.6
python-version: 3.7
- name: Install Flake8
run: |
pip install flake8-pyproject
Expand Down
55 changes: 43 additions & 12 deletions cc.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,47 @@
"""Sandbox experimental file used to quickly feature test features of the package
"""
"""Sandbox experimental file used to quickly feature test features of the package"""

from src.masoniteorm.query import QueryBuilder
from src.masoniteorm.connections import MySQLConnection, PostgresConnection
from src.masoniteorm.query.grammars import MySQLGrammar, PostgresGrammar
from src.masoniteorm.models import Model
from src.masoniteorm.relationships import has_many
import inspect

from src.masoniteorm.connections import MySQLConnection, PostgresConnection
from src.masoniteorm.models import Model
from src.masoniteorm.query import QueryBuilder
from src.masoniteorm.query.grammars import MySQLGrammar, PostgresGrammar
from src.masoniteorm.relationships import belongs_to, has_many

# builder = QueryBuilder(connection=PostgresConnection, grammar=PostgresGrammar).table("users").on("postgres")



# print(builder.where("id", 1).or_where(lambda q: q.where('id', 2).or_where('id', 3)).get())


class Logo(Model):
__connection__ = "t"
__table__ = "logos"
__dates__ = ["created_at", "updated_at"]

@belongs_to("id", "article_id")
def article(self):
return Article

@belongs_to("user_id", "id")
def user(self):
return User


class Article(Model):
__connection__ = "t"
__table__ = "articles"
__dates__ = ["created_at", "updated_at"]

@has_many("id", "article_id")
def logos(self):
return Logo

@belongs_to("user_id", "id")
def user(self):
return User


class User(Model):
__connection__ = "t"
__table__ = "users"
Expand All @@ -23,15 +50,19 @@ class User(Model):
@has_many("id", "user_id")
def articles(self):
return Article


class Company(Model):
__connection__ = "sqlite"


# /Users/personal/programming/masonite/packages/orm/src/masoniteorm/query/QueryBuilder.py

# user = User.create({"name": "phill", "email": "phill"})
# print(inspect.isclass(User))
user = User.first()
user = User.with_("articles.logos.user").first()
# user.update({"verified_at": None, "updated_at": None})
print(user.serialize())
# print(user.articles)

# print(user.serialize())
# print(User.first())
print(user.serialize())
# print(User.first())
File renamed without changes.
Binary file modified orm.sqlite3
Binary file not shown.
14 changes: 12 additions & 2 deletions src/masoniteorm/collection/Collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -505,8 +505,18 @@ def _get_value(self, key):
items = []
for item in self:
if isinstance(key, str):
if hasattr(item, key) or (key in item):
items.append(getattr(item, key, item[key]))
if hasattr(item, key):
items.append(getattr(item, key))
elif isinstance(item, dict) and key in item:
items.append(item[key])
elif isinstance(key, int):
if isinstance(item, (list, tuple)):
try:
items.append(item[key])
except IndexError:
pass
elif isinstance(item, dict) and key in item:
items.append(item[key])
elif callable(key):
result = key(item)
if result:
Expand Down
55 changes: 41 additions & 14 deletions src/masoniteorm/models/Model.py
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ def relations_to_dict(self):
new_dic.update({key: {}})
else:
if value is None:
new_dic.update({key: {}})
new_dic.update({key: None})
continue
elif isinstance(value, list):
value = Collection(value).serialize()
Expand Down Expand Up @@ -802,7 +802,9 @@ def method(*args, **kwargs):
return method

if attribute in self.__dict__.get("_relationships", {}):
return self.__dict__["_relationships"][attribute]
value = self.__dict__["_relationships"][attribute]
print(f"[Model.__getattr__] Accessed relationship '{attribute}', value: {value} (type: {type(value)})")
return value

if attribute not in self.__dict__:
name = self.__class__.__name__
Expand Down Expand Up @@ -1061,26 +1063,54 @@ def detach_many(self, relation, relating_records):
related.detach(self, related_record)

def related(self, relation):
related = getattr(self.__class__, relation)
related = getattr(self, relation)
return related.relate(self)

def get_related(self, relation):
related = getattr(self.__class__, relation)
return related

def attach(self, relation, related_record):
related = getattr(self.__class__, relation)
return related.attach(self, related_record)
"""Attach a related record to the model.

Args:
relation: The name of the relationship
related_record: The related record to attach

Returns:
The attached record
"""
relationship = getattr(self.__class__, relation)
if hasattr(relationship, 'attach'):
return relationship.attach(self, related_record)
return related_record

def attach_related(self, relation, related_record):
"""Attach a related record to the model.

Args:
relation: The name of the relationship
related_record: The related record to attach

Returns:
The attached record
"""
return self.attach(relation, related_record)

def detach(self, relation, related_record):
related = getattr(self.__class__, relation)
"""Detach a related record from the model.

if not related_record.is_created():
related_record = related_record.create(related_record.all_attributes())
else:
related_record.save()
Args:
relation: The name of the relationship
related_record: The related record to detach

return related.detach(self, related_record)
Returns:
The detached record
"""
relationship = getattr(self.__class__, relation)
if hasattr(relationship, 'detach'):
return relationship.detach(self, related_record)
return related_record

def save_quietly(self):
"""This method calls the save method on a model without firing the saved & saving observer events. Saved/Saving
Expand Down Expand Up @@ -1120,9 +1150,6 @@ def delete_quietly(self):
self.with_events()
return delete

def attach_related(self, relation, related_record):
return self.attach(relation, related_record)

@classmethod
def filter_fillable(cls, dictionary: Dict[str, Any]) -> Dict[str, Any]:
"""
Expand Down
6 changes: 4 additions & 2 deletions src/masoniteorm/models/Pivot.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from .Model import Model
# Remove: from .Model import Model


class Pivot(Model):
class Pivot:
__primary_key__ = "id"
__fillable__ = ["*"]
__table__ = None
Loading
Loading