Relationships

Last updated 8 months ago

Introduction

By default, Masonite Entry does not show relationships in the API call and leaves it up to the developer to choose which relationships will show. Luckily, adding relationships is as easy as the rest of the features.

Getting Started

Having a relationship on our model might look something like this:

from config.database import Model
from orator.orm import belongs_to
class User(Model):
''' User Model '''
__fillable__ = ['name', 'email', 'password']
__auth__ = 'email'
@belongs_to('id', 'user_id')
def tokens(self):
from entry.api.models.OAuthToken import OAuthToken
return OAuthToken

We have a tokens relationship that belongs to the oauth_tokens table represented by the OAuthToken model. Out of the box, our API calls will not show these relationships.

Showing Relationships

If we ran a GET request on /api/users now we will see something like:

[
{
"id": 1,
"name": "Joseph",
"email": "email1@gmail.com",
"created_at": "2018-03-23T21:56:25.081413",
"updated_at": "2018-03-23T22:05:00.820837"
}
]

We see that we don't have access to our tokens relationship. We can simply specify which relationship we want to see in our API call by adding the relationships attribute to our resource. This attribute is a list of the method names of our relationships.

from entry.api.Resource import Resource
from entry.api.JsonSerialize import JsonSerialize
from app.User import User
class UserResource(Resource, JsonSerialize):
model = User
exclude = ['password', 'remember_token']
relationships = ['tokens']

If our user actually has a record inside the oauth_tokens table then our API call should now look like:

[
{
"id": 1,
"name": "Joseph",
"email": "email1@gmail.com",
"created_at": "2018-03-23T22:04:42.791668",
"updated_at": "2018-03-24T01:25:21.757573",
"tokens": {
"id": 1,
"user_id": 1,
"name": "default",
"scope": "user:data user:companies",
"token": "41609b13198447e89a18828822ca7aa1",
"created_at": "2018-03-24T01:13:38.343711",
"updated_at": "2018-03-24T01:25:21.761145"
}
}
]

If there is no record found then it will not show anything as a relationship. You may have an API call that looks like:

[
{
"id": 1,
"name": "Joseph",
"email": "email1@gmail.com",
"created_at": "2018-03-23T22:04:42.791668",
"updated_at": "2018-03-24T01:25:21.757573",
"tokens": {
"id": 1,
"user_id": 1,
"name": "default",
"scope": "user:data user:companies",
"token": "41609b13198447e89a18828822ca7aa1",
"created_at": "2018-03-24T01:13:38.343711",
"updated_at": "2018-03-24T01:25:21.761145"
}
},
{
"id": 2,
"name": "Mike",
"email": "email2@gmail.com",
"created_at": "2018-03-23T22:04:42.791668",
"updated_at": "2018-03-24T01:25:21.757573",
}
]

Excluding Relationship Fields

We see that we have some arbitrary data that might not be useful like the relationships id and user_id. We can remove those fields by using the exclude_relationship_fields attribute. This attribute takes a dictionary with the key of the relationship name and the value as a list of fields we want to remove.

from entry.api.Resource import Resource
from entry.api.JsonSerialize import JsonSerialize
from app.User import User
class UserResource(Resource, JsonSerialize):
model = User
exclude = ['password', 'remember_token']
relationships = ['tokens']
exclude_relationship_fields = {
# relationship # fields to exclude
'tokens': ['id', 'user_id']
}

If we re-run our API call we should now see:

[
{
"id": 1,
"name": "Joseph",
"email": "email1@gmail.com",
"created_at": "2018-03-23T22:04:42.791668",
"updated_at": "2018-03-24T01:25:21.757573",
"tokens": {
"name": "default",
"scope": "user:data user:companies",
"token": "41609b13198447e89a18828822ca7aa1",
"created_at": "2018-03-24T01:13:38.343711",
"updated_at": "2018-03-24T01:25:21.761145"
}
}
]