rm table
Look up the scenario you need to implement on the left, then use the template implementation on the right in your code.
| Relationship Scenario | Example Python Implementation | |||
|---|---|---|---|---|
Implementing one to one relationships between class X and Y |
||||
| #1. |
1 → 1, directional, all methods on X
Singular API No API
______________ ______________
| X | | Y |
|______________| |______________|
| | | |
|void setY(y) |1 1| |
|Y getY() |⎯⎯⎯⎯⎯⎯⎯⎯⎯→| |
|void clearY()| | |
|______________| |______________|
Note: The |
class X:
def __init__(self):
rm.enforce("xtoy", "onetoone", "directional")
def setY(self, y):
rm.add_rel(self, y, "xtoy")
def getY(self):
rm.find_target(source=self, rel_id="xtoy")
def clearY(self):
rm.remove_rel(self, self.getY(), "xtoy")
class Y: pass |
||
| #2. |
1 → 1, directional, all methods on Y
No API Singular API
______________ ______________
| X | | Y |
|______________| |______________|
| | | |
| |1 1| setX(x) |
| |⎯⎯⎯⎯⎯⎯⎯⎯→ | getX() |
| | | clearX() |
|______________| |______________|
|
class X: pass
class Y:
def __init__(self):
rm.enforce("xtoy", "onetoone", "directional")
def setX(self, x):
rm.add_rel(x, self, "xtoy")
def getX(self):
rm.find_source(target=self, rel_id="xtoy")
def clearX(self):
rm.remove_rel(self.getX(), self, "xtoy")
|
||
| #3. |
1 ←→ 1, bi-directional, methods on both X and Y Singular API Singular API ______________ ______________ | X | | Y | |______________| |______________| | | | | |void setY(y) |1 1| setX(x) | |Y getY() | ←⎯⎯⎯⎯→ | getX() | |void clearY()| | clearX() | |______________| |______________| |
class X:
def __init__(self):
rm.enforce("xy", "onetoone", "bidirectional")
def setY(self, y):
rm.add_rel(self, y, "xy")
def getY(self):
rm.find_target(self, "xy")
def clearY(self):
rm.remove_rel(self, self.getY(), "xy")
class Y:
def __init__(self):
rm.enforce("xy", "onetoone", "bidirectional")
def setX(self, x):
rm.add_rel(self, x, "xy")
def getX(self):
rm.find_target(self, "xy")
def clearX(self):
rm.remove_rel(self, self.getX(), "xy")
|
||
| #3A. |
1 ←→ 1, bi-directional, methods on both X and Y Alternative implementation of scenario 3, using "directional" and a backpointer method
diagram as above
|
class X:
def __init__(self):
rm.enforce("xy", "onetoone", "directional") # different to 3.
# uses 'directional' not 'bidirectional'
def setY(self, y):
rm.add_rel(self, y, "xy") # same as 3.
def getY(self):
rm.find_target(self, "xy") # same as 3.
def clearY(self):
rm.remove_rel(self, self.getY(), "xy") # same as 3.
class Y:
def __init__(self):
rm.enforce("xy", "onetoone", "directional") # different to 3.
# uses 'directional' not 'bidirectional'
# redundant call since already called in X's constructor
def setX(self, x): # different to 3.
rm.add_rel(self, x, "xy")
# source and target params swapped
def getX(self): # different to 3.
rm.find_source(self, "xy")
# uses 'find_source' not 'find_target'
def clearX(self): # different to 3.
rm.remove_rel(self, self.getX(), "xy")
# source and target params swapped
|
||
|
Notes on Scenario 3 and 3A:
|
||||
Implementing one to many relationships between class X and Y |
||||
| #4. |
1 → *, directional, all methods on X Plural API No API _____________ ______________ | X | | Y | |_____________| |______________| | | | | |addY(y) |1 *| | |getAllY() | ⎯⎯⎯⎯⎯⎯→ | | |removeY(y) | | | |_____________| |______________| |
class X:
def __init__(self):
rm.enforce
def addY(self, y):
rm.add_rel(self, y, "xtoy")
def getAllY(self):
rm.find_targets(self, "xtoy")
def removeY(self, y):
rm.remove_rel(self, y, "xtoy")
class Y: # no methods on rhs pass |
||
| #5. |
1 ←→ *, bi-directional, methods on both X and Y
Plural API Singular API
_____________ ______________
| X | | Y |
|_____________| |______________|
| | | |
|addY(y) |1 *| setX(x) |
|getAllY() | ←⎯⎯⎯⎯→ | getX() |
|removeY(y) | | clearX() |
|_____________| |______________|
Since there are two API's, one on each class, this makes it a bidirectional relationship. However - there still remains a sense of directionality because the one to many is directional i.e. the the lhs. 'one' side is the X and the rhs. 'many' side is the Y, not the other way around. |
class X:
def __init__(self):
rm.enforce("xtoy", "onetomany", "bidirectional")
def addY(self, y):
rm.add_rel(self, y, "xtoy")
def getAllY(self):
rm.find_targets(self, "xtoy")
def removeY(self, y):
rm.remove_rel(self, y, "xtoy")
class Y:
# though bi, there is still a direction!
def setX(self, x):
rm.add_rel(x, self, "xtoy")
def getX(self):
rm.find_target(self, "xtoy")
def clearX(self):
rm.remove_rel(self, self.getX(), "xtoy")
|
||
| #5A. |
1 ←→ *, bi-directional, methods on both X and Y Alternative implementation of scenario 5, using "directional" and a backpointer method
diagram as above
|
class X:
def __init__(self):
rm.enforce("xtoy", "onetomany", "directional") # different to 5
# uses 'directional' not 'bidirectional'
def addY(self, y):
rm.add_rel(self, y, "xtoy") # same as 5.
def getAllY(self):
rm.find_targets(self, "xtoy") # same as 5.
def removeY(self, y):
rm.remove_rel(self, y, "xtoy") # same as 5.
class Y:
def setX(self, x):
rm.add_rel(x, self, "xtoy") # same as 5.
def getX(self):
rm.find_source(self, "xtoy") # different to 5
# uses 'find_source' not 'find_target'
def clearX(self):
rm.remove_rel(self.getX(), self, "xtoy") # different to 5
# source and target params swapped
|
||
Implementing many to one relationships between class X and Y |
||||
| #6. |
* → 1, directional, all methods on Y
No API Plural API
______________ ______________
| X | | Y |
|______________| |______________|
| | | |
| |* 1|addX(x) |
| | ⎯⎯⎯⎯⎯⎯→ |getAllX() |
| | |removeX(x) |
|______________| |______________|
|
DRAFT API (not tested) class X: pass
class Y:
def addX(x) -> None:
rm.add_rel(x, this, "xtoy")
def getAllX() -> List:
return rm.find_sources(this, "xtoy")
def removeX(x) -> None:
rm.remove_rel(x, this, "xtoy")
|
||
| #7. |
* ←→ 1, bi-directional, methods on both X and Y Singular API Plural API ______________ ______________ | X | | Y | |______________| |______________| | | | | |void setY(y) |* 1|addX(x) | |Y getY() | ←⎯⎯⎯⎯→ |getAllX() | |void clearY()| |removeX(x) | |______________| |______________| |
DRAFT API (not tested)
class X:
def setY(y) -> None:
rm.add_rel(this, y, "xtoy")
def getY() -> Y:
rm.find_target(this, "xtoy")
def clearY() -> None:
rm.remove_rel(this, getY(), "xtoy")
class Y:
def addX(x) -> None:
rm.add_rel(x, this, "xtoy")
def getAllX() -> List:
rm.find_sources(this, "xtoy")
def removeX(x) -> None:
rm.remove_rel(x, this, "xtoy")
|
||
Implementing many to many relationships between class X and Y |
||||
| #8. |
* → *, directional, all methods on X Plural API No API _____________ ______________ | X | | Y | |_____________| |______________| | | | | |addY(y) |* *| | |getAllY() | ⎯⎯⎯⎯⎯⎯→ | | |removeY(y) | | | |_____________| |______________| |
DRAFT API (TODO, not tested) |
||
| #9. |
* → *, directional, all methods on Y
No API Plural API
______________ ______________
| X | | Y |
|______________| |______________|
| | | |
| |* *|addX(x) |
| | ⎯⎯⎯⎯⎯⎯→ |getAllX() |
| | |removeX(x) |
|______________| |______________|
|
DRAFT API (TODO, not tested) |
||
| #10. |
* ←→ *, bi-directional, methods on both X and Y Plural API Plural API ______________ ______________ | X | | Y | |______________| |______________| | | | | | addY(y) |* *| addX(x) | | getAllY() | ←⎯⎯⎯⎯→ | getAllX() | | removeY(y) | | removeX(x) | |______________| |______________| |
DRAFT API (TODO, not tested) |
||