2
votes

I am having some trouble with setting up a hasOne relation, which probably comes from me understanding the relation wrongly?

I have 2 Models, one user model, and one location model. What I want to add now is a relation between user and location, meaning a user has a current location. But if I set up a hasOne relation on the user model with the location, I end up with a userId property in the location. But this is completely wrong, since several users can have the same current location, so the user model should store the location id, not the location the user id. So how can I achieve what I want, so that I can afterwards query the user and include the current location?

I can of course add a property to the user and store the id of the location there, but then I can't as easily include the location in a user request. So I would prefer using relations to achieve this.

2

2 Answers

3
votes

Your problem is a bit unclear, given the comments of Brian's post, but if you absolutely need Users to share a given set of locations then you would be better off using User belongsTo location.

This will create a locationId field in User, and you will be able to GET api\Users\{userId}\location

Eventually, you can set a location hasMany User to retrieve from a given location all the users in there

2
votes

The relation name is referring to the relational meaning of "has one," which means that for each user, there exists one (and only one) entry in the location table. Each user "has one" entry in the location table, and if your data needs to show that two users have the same location, it just means the location table would store identical location data with different userIds. This is still perfectly fine for relational mapping, and allows you to do User.location calls.

What you are looking for is slightly different, which would be "Location hasMany Users," because you will be sharing location entries with multiple users. Read this as "for each location entry, many users could share it." You'll have to query a bit differently and use the include: ['location'] filter when you want to return the User with location data included (otherwise you'll only get the locationId value).

Relation builder:

$ slc loopback:relation
? Select the model to create the relationship from: Location
? Relation type: has many
? Choose a model to create a relationship with: user
? Enter the property name for the relation: users
? Optionally enter a custom foreign key:
? Require a through model? No

location.json:

{
  "name": "Location",
  "base": "PersistedModel",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {
    "lat": {
      "type": "number"
    },
    "long": {
      "type": "number"
    }
  },
  "validations": [],
  "relations": {
    "users": {
      "type": "hasMany",
      "model": "user",
      "foreignKey": "locationId"
    }
  },
  "acls": [],
  "methods": {}
}