This will not create a reference loop in modeling language, right?
participant Owner identified by name {
o String name
o Car[] cars
}
asset Car identified by plateNumber {
o String plateNumber
--> Owner owner
}
Correct - it won't. Your model simply creates an array of cars in participant class Owner and a relationship (identifier) to owner from the asset class Car. This is perfectly fine and reasonable as for as modeling goes and the circular nature of what you're asking.
Related
I am trying to model a company and its relevant employee strucutre. I have 3 tables (company, position, employee) as below, and company haveMany position, and employee haveMany position. Position belongs to company, and position belongs to employee.
However, different position have some common field like onboard date, but have some fields are different. Forexmaple, CEO has a gurantee employment period, while other position dont. Quite a number of field is different too for different position.
In that case, should I using polymorphic to model? but as the company has quite a number of different position, this will create quite a lot new table in the database.
Do you have any advice on how to model different positions?
Companies
id
Position
Positions
id
type [CEO, manager, director, clerk, etc]
company_id
employee_id
Onboard Date
Ceased Date
Employees
id
position id
In that case, should I using polymorphic to model? but as the company has quite a number of different position, this will create quite a lot new table in the database.
No, why would be?
First of all, it should be manyToMany relation and not oneToMany because if you have two companies both of those can have CEO (for example) position and if you set $position->belongsTo(Company::class); it couldn't work.
It is polymorph relation there with positions as polymorphic angle of that triangle.
You would need
// companies
id
name
// employees
id
name
// positions
id
name
// positionables
position_id
positionable_id
positionable_type
With this, your models would be
class Company extends Model
{
public function positions()
{
return $this->morphToMany(Position::class, 'positionable');
}
}
class Employee extends Model
{
public function positions()
{
return $this->morphToMany(Position::class, 'positionable');
}
}
class Position extends Model
{
public function companies()
{
return $this->morphedByMany(Company::class, 'positionable');
}
public function employees()
{
return $this->morphedByMany(Company::class, 'positionable');
}
}
It allows you to set positions, companies and employees separately. Meaning, From dashboard you can make some new positions that will be available on frontend from select options let's say. Of course you should allow company and to employee to create new position (I suggest) and not just to use existing one but it could be out of scope of this question now: in example, when (and if) company creates new position (instead of selecting existing ones from options list), you would first create that position and store it into positions table and then associate company with it. Also, when using this kind of chained inputs to DB don't forget to use DB transactions. Into positionables table you would set other fields important for each relation (onboard_date, ceased_date, etc).
Documentation is very good and consult it if something is not clear (I hope it is already).
Disclaimer: I don't know rest of your project business plan and rest of project's requirements but for these three entities this is the best structure you can go with. I have set just mandatory members to models and tables for this example. Also in offered answer, I presumed use of Laravel's naming convention that's blindly followd from docs and this repo.
If the fields have no relationship with other tables, one possible way is to have a key-value table to store those fields and values:
position_fields
- id
- position_id
- key
- value
You can hence store the fields in key and the respective value in value. Then you may overwrite the __get magic method in Position model e.g.
public function __get($key){
$position_field = $this->hasMany(PositionField::class)->where('key', $field)->first();
return !!$position_field ? $position_field->value : $this->getAttribute($key);
}
I want to create a new Role extending two existing roles. So is it possible in composer modelling language for a participant to extend multiple participants?
It is not likely to be supported as multiple inheritance is tricky and you would be forced into design issues in Object Oriented systems - Diamond Problem in multiple inheritance .
A Participant Type can only Extend one Participant type.
Using Concepts may allow you "re-use" elements of the model and ensure consistency.
concept Manager {
o String MTitle
o String QualificationType
}
concept Engineer {
o String ETitle
o String CharterCertType
}
participant Mgr identified by mID {
o String mID
o String name
o Manager manager
}
participant Engr identified by eID {
o String eID
o String name
o Engineer engineer
}
participant EMgr identified by emID {
o String emID
o String name
o Manager manager
o Engineer engineer
}
The modelling language is covered in Modelling Language and Model Compatibility
I have defined Asset as :
asset PurchaseOrderAsset identified by orderId {
o String orderId
--> SupplierChainParticipant createdBy
--> SupplierChainParticipant assignedTo
o String description
o String status
o Integer quantity
o String assetId
o PurchaseOrderAsset[] subPurchaseOrders
}
Now, When I am trying to create Asset, I am getting error as "InternalError: too much recursion". i am facing this error in composer playground.
Can we have self-join relationship or not?
This is a bug, please create an issue for it, attaching your example BNA.
To workaround it I recommend that you create a concept for the line items of a purchase order. Conceptually those "sub" purchase orders are not assets, because they are not addressable through a registry.
Please also see: Different between 'o' and arrow symbol used in .cto file?
In Spring data neo4j 3.x To create relation ship between two nodes and relationship contains set of properties earlier used to achieve this by apis
create :
n4jOperations.createRelationshipBetween(Object start, Object end, Class<R> relationshipEntityClass, String relationshipType, boolean allowDuplicates);
delete:
n4jOperations.deleteRelationshipBetween(Object start, Object end, String type);
get:
n4jOperations.getRelationshipBetween( from, to, relationshipClass, relationshipType );
But after migration i didnt't find above apis
as per docs says
#NodeEntity
public class Student {
private String name;
#Relationship(type = "ENROLLED")
private Set<Enrollment> enrollments;
}
By repo.save(Student);
//Relation creation was possible but new api's how can i achieve below use cases
1.How can avoid duplicate relation creation?
2.get Relation ship between two nodes ?
2.delete relation ship between two nodes ?
SDN 4 does not provide low-level graph-operations like setting nodes and relationships directly.
Relationships in the graph are modelled and manipulated using object references in your domain classes. They come in two flavours: implicit and explicit. Implicit relationships are described by simple references between two node entities, e.g. Customer and Address:
class Customer {
#Relationship(type="LIVES_AT")
Address address; // implied (:Customer)-[:LIVES_AT]->(:Address)
...
}
Explicit relationships are modelled using RelationshipEntity objects, and are allowed to have properties (but don't have to). They are still accessed as references in your domain model.
class Person {
#Relationship(type="RATED")
List<Rating> ratings
}
class Movie {
}
#RelationshipEntity(type="RATED")
class Rating {
#StartNode Person person;
#EndNode Movie movie;
int stars;
}
Note: If you don't need properties on a particular relationship, you don't need to use a RelationshipEntity.
To answer your specific questions:
1) SDN 4.0 doesn't create duplicate relationships. No matter how many times you persist a specific object reference, it will represented by only one relationship in the graph.
2) Hopefully that is clear now!
3) Setting an object reference to null and saving the parent object will remove the relationship. Or, if the reference is part of Collection, remove it from the collection. You must ensure that the object references are removed from both sides. For example if A holds a reference to B and B holds a reference to A, you must remove A's reference to B as well as B's reference to A.
I have three models.
PERSON (hasOne(EMPLOYEE), hasMany(CHILDREN))
id,
name
EMPLOYEE
id,
person_id
CHILDREN
id,
person_id
I want to add a child to person model but i have access to EMPLOYEE_ID. I tried to code but it doesn't work.
$employee->person()->children()->save($child);
and
$employee->person()->children()->associate($child);
But both doesn't work. I don't know if this can be accomplished by just one line of code.
Try this way, When you are calling person() it will return the relation instead of the object itself.
$employee->person->children()->save($child);