How to create one-to-many relationship React native Realm SDK

I have defined two collections in my code, Team and Player. I can’t figure out how to turn it into a JSON schema in the realm UI, with the relationships. I want the team to contain a list of players.

export const PlayerSchema = {
	name: 'Player',
	properties: {
		_id: 'objectId?',
		name: 'string?',
		position: 'string?',
		uri: 'string?',
	},
	primaryKey: '_id',
};

export const TeamSchema = {
	name: 'Team',
	properties: {
		_id: 'objectId?',
		players: 'Player[]',
		team_image_url: 'string?',
		team_name: 'string?',
		user_id: 'string?',
	},
	primaryKey: '_id',
};

I think I figured it out like this:

{
  "title": "Player",
  "properties": {
    "_id": {
      "bsonType": "objectId"
    },
    "club_id": {
      "bsonType": "objectId"
    },
    "name": {
      "bsonType": "string"
    },
    "club": {
      "bsonType": "string"
    },
    "position": {
      "bsonType": "string"
    },
    "uri": {
      "bsonType": "string"
    }
  }
}
{
  "title": "Team",
  "properties": {
    "_id": {
      "bsonType": "objectId"
    },
    "team_name": {
      "bsonType": "string"
    },
    "team_image_url": {
      "bsonType": "string"
    },
    "user_id": {
      "bsonType": "string"
    },
    "players": {
      "bsonType": "array",
      "items": {
        "bsonType": "objectId"
      }
    }
  }
}

Hi @Mads_Haerup! You may want to consider an inverse relationship in your schemas.

Looks like you’ve got part of it already. TeamSchema has players: Player[], which is correct. However, you need to add a specific field to Player to complete the relationship.

export const PlayerSchema = {
	name: 'Player',
	properties: {
		_id: 'objectId?',
		name: 'string?',
		position: 'string?',
		uri: 'string?',
        // assignee field links the Player back to Team.players.
        assignee: {
          type: 'linkingObjects',
          objectType: 'Team',
          property: 'players'
        }
	},
	primaryKey: '_id',
};

To actually add the player to a team, you need to query for your team. If you’re using the Realm React library, it would look something like this:

const team = useQuery(Team).filtered(`team_name == ${nameOfTeamToFind}`)[0];

After you query for your team, create a new Player object. Then, push the player to Team.players:

team.players.push(newPlayer)

Hopefully, some of this helps!

Hi @Kyle_Rollins , Thanks for the answer, that helped me out a lot. Before Closing I just have one more pressing error to solve.

I set the logged in team in a context. But when I’m filtering for it, like you showed above
I get this error:

Invalid predicate: ‘team_name == DC United’: syntax error, unexpected identifier, expecting end of file

With the code below:

const loggedInTeam = useContext(TeamContext);

const team = useQuery("Team").filtered(`team_name == ${loggedInTeam`)[0];

But with this code, it’s fine.

const team = useQuery("Team").filtered(`team_name == 'DC United'`)[0];

I’m glad I could help, @Mads_Haerup!

I noticed a couple things that might be causing the error.

  • Is what you shared above exactly what’s in your code? In the example you shared, you’re missing a closing bracket: team_name == ${loggedInTeam} ← need that last bracket
  • Is loggedInTeam an object that matches your team schema? If so, you’ll need to compare team_name to ${loggedInTeam.name}. team_name is just one property on your team schema. You could also filter by _id. That would look like this:
    const team = useQuery(Team).filtered(`_id == oid(${loggedInTeam._id})`)[0];
    
    • You need oid() wrapped around _id values so that we’re comparing the same types.

@Kyle_Rollins
I just up messed up the formatting here. I didn’t forget the bracket in my code.

LoggedInTeam is not part of my Schema. LoggedInTeam was just a context string. in this example loggInTeam was a string set to ‘DC United’. So essentially loggedInTeam and ‘DC United’ is the same thing, so I was wondering why it didn’t work. Anyways, I’m doing some restructuring, so I will close the original question and open a new, if It is necessary, Thanks for the help.

1 Like