Skip to content
This repository has been archived by the owner on May 14, 2024. It is now read-only.

Commit

Permalink
Adding support for extra conditions on relationships.
Browse files Browse the repository at this point in the history
Fixes #26
  • Loading branch information
sdispater committed Dec 13, 2015
1 parent 149a7ce commit 045519e
Show file tree
Hide file tree
Showing 17 changed files with 386 additions and 73 deletions.
8 changes: 4 additions & 4 deletions orator/orm/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,14 +490,14 @@ def get_relation(self, relation):
from .relations import Relation

with Relation.no_constraints(True):
query = getattr(self.get_model(), relation)()
rel = getattr(self.get_model(), relation)()

nested = self._nested_relations(relation)

if len(nested) > 0:
query.get_query().with_(nested)
rel.get_query().with_(nested)

return query
return rel

def _nested_relations(self, relation):
"""
Expand Down Expand Up @@ -1102,11 +1102,11 @@ def __getattr__(self, item, *args):
try:
object.__getattribute__(self, item)
except AttributeError:
# TODO: macros
return self.__dynamic(item)

def __copy__(self):
new = self.__class__(copy.copy(self._query))
new.set_model(self._model)

return new

8 changes: 2 additions & 6 deletions orator/orm/relations/belongs_to.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@

class BelongsTo(Relation):

_other_key = None
_relation = None
_foreign_key = None

def __init__(self, query, parent, foreign_key, other_key, relation):
"""
:param query: A Builder instance
Expand Down Expand Up @@ -188,9 +184,9 @@ def get_other_key(self):
def get_qualified_other_key_name(self):
return '%s.%s' % (self._related.get_table(), self._other_key)

def new_instance(self, model):
def _new_instance(self, model):
return BelongsTo(
self._related.new_query(),
self.new_query(),
model,
self._foreign_key,
self._other_key,
Expand Down
4 changes: 2 additions & 2 deletions orator/orm/relations/belongs_to_many.py
Original file line number Diff line number Diff line change
Expand Up @@ -852,9 +852,9 @@ def get_table(self):
def get_relation_name(self):
return self._relation_name

def new_instance(self, model):
def _new_instance(self, model):
relation = BelongsToMany(
self._related.new_query(),
self.new_query(),
model,
self._table,
self._foreign_key,
Expand Down
4 changes: 2 additions & 2 deletions orator/orm/relations/has_many.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ def match(self, models, results, relation):
"""
return self.match_many(models, results, relation)

def new_instance(self, model):
def _new_instance(self, model):
return HasMany(
self._related.new_query(),
self.new_query(),
model,
self._foreign_key,
self._local_key
Expand Down
8 changes: 2 additions & 6 deletions orator/orm/relations/has_many_through.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@

class HasManyThrough(Relation):

_first_key = None
_second_key = None
_far_parent = None

def __init__(self, query, far_parent, parent, first_key, second_key):
"""
:param query: A Builder instance
Expand Down Expand Up @@ -183,9 +179,9 @@ def _get_select_columns(self, columns=None):
def get_has_compare_key(self):
return self._far_parent.get_qualified_key_name()

def new_instance(self, model):
def _new_instance(self, model):
return HasManyThrough(
self._related.new_query(),
self.new_query(),
model,
self._parent,
self._first_key,
Expand Down
4 changes: 2 additions & 2 deletions orator/orm/relations/has_one.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ def match(self, models, results, relation):
"""
return self.match_one(models, results, relation)

def new_instance(self, model):
def _new_instance(self, model):
return HasOne(
self._related.new_query(),
self.new_query(),
model,
self._foreign_key,
self._local_key
Expand Down
3 changes: 0 additions & 3 deletions orator/orm/relations/has_one_or_many.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@

class HasOneOrMany(Relation):

_local_key = None
_foreign_key = None

def __init__(self, query, parent, foreign_key, local_key):
"""
:type query: orator.orm.Builder
Expand Down
9 changes: 0 additions & 9 deletions orator/orm/relations/morph_many.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,3 @@ def match(self, models, results, relation):
:type relation: str
"""
return self.match_many(models, results, relation)

def new_instance(self, parent):
return MorphMany(
self._related.new_query(),
parent,
self._morph_type,
self._foreign_key,
self._local_key
)
9 changes: 0 additions & 9 deletions orator/orm/relations/morph_one.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,3 @@ def match(self, models, results, relation):
:type relation: str
"""
return self.match_one(models, results, relation)

def new_instance(self, parent):
return MorphOne(
self._related.new_query(),
parent,
self._morph_type,
self._foreign_key,
self._local_key
)
12 changes: 9 additions & 3 deletions orator/orm/relations/morph_one_or_many.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@

class MorphOneOrMany(HasOneOrMany):

_morph_type = None
_morph_name = None

def __init__(self, query, parent, morph_type, foreign_key, local_key):
"""
:type query: orator.orm.Builder
Expand Down Expand Up @@ -192,3 +189,12 @@ def get_plain_morph_type(self):

def get_morph_name(self):
return self._morph_name

def _new_instance(self, parent):
return self.__class__(
self.new_query(),
parent,
self._morph_type,
self._foreign_key,
self._local_key
)
9 changes: 2 additions & 7 deletions orator/orm/relations/morph_to.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@

class MorphTo(BelongsTo):

_morph_type = None
_models = Collection()
_dictionary = None
_with_trashed = None

def __init__(self, query, parent, foreign_key, other_key, type, relation):
"""
:type query: orator.orm.Builder
Expand Down Expand Up @@ -191,9 +186,9 @@ def _use_with_trashed(self, query):

return query

def new_instance(self, model, related=None):
def _new_instance(self, model, related=None):
return MorphTo(
self._related.new_query() if not related else related.new_query(),
self.new_query(related),
model,
self._foreign_key,
self._other_key if not related else related.get_key_name(),
Expand Down
14 changes: 6 additions & 8 deletions orator/orm/relations/morph_to_many.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@

class MorphToMany(BelongsToMany):

_name = None
_inverse = None
_morph_type = None
_morph_name = None

def __init__(self, query, parent, name, table,
foreign_key, other_key, relation_name=None, inverse=False):
"""
Expand Down Expand Up @@ -38,7 +33,10 @@ def __init__(self, query, parent, name, table,
self._morph_type = name + '_type'
self._morph_name = query.get_model().get_morph_name() if inverse else parent.get_morph_name()

super(MorphToMany, self).__init__(query, parent, table, foreign_key, other_key, relation_name)
super(MorphToMany, self).__init__(
query, parent, table,
foreign_key, other_key, relation_name
)

def _set_where(self):
"""
Expand Down Expand Up @@ -114,9 +112,9 @@ def get_morph_type(self):
def get_morph_name(self):
return self._morph_name

def new_instance(self, model):
def _new_instance(self, model):
return MorphToMany(
self._related.new_query(),
self.new_query(),
model,
self._name,
self._table,
Expand Down
29 changes: 28 additions & 1 deletion orator/orm/relations/relation.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from contextlib import contextmanager
from ...query.expression import QueryExpression
from ..collection import Collection
from ..builder import Builder


class Relation(object):
Expand All @@ -20,6 +21,7 @@ def __init__(self, query, parent):
self._query = query
self._parent = parent
self._related = query.get_model()
self._extra_query = None

self.add_constraints()

Expand Down Expand Up @@ -148,7 +150,10 @@ def get_base_query(self):
return self._query.get_query()

def merge_query(self, query):
self._query.merge_wheres(query.wheres, query.get_query().get_raw_bindings()['where'])
if isinstance(query, Builder):
query = query.get_query()

self._query.merge(query)

def get_parent(self):
return self._parent
Expand Down Expand Up @@ -194,6 +199,28 @@ def wrap(self, value):
def set_parent(self, parent):
self._parent = parent

def set_extra_query(self, query):
self._extra_query = query

def new_query(self, related=None):
if related is None:
related = self._related

query = related.new_query()

if self._extra_query:
query.merge(self._extra_query.get_query())

return query

def new_instance(self, model, **kwargs):
new = self._new_instance(model, **kwargs)

if self._extra_query:
new.set_extra_query(self._extra_query)

return new

def __dynamic(self, method):
attribute = getattr(self._query, method)

Expand Down
Loading

0 comments on commit 045519e

Please sign in to comment.