Search code examples
node.jsrestexpressloopbackjs

Loopback - how to get id of user and insert into related model? (hasMany)


What I am trying to figure out is how to get the id of the current authenticated user and use that when creating records in the DB as a foreign key of a different model?

To be more specific I need to get the id of the current authenticated user (model: CommonUser) and use that id as a FK when creating a new Event.

The relationships:

I have created a Model based on the User model called CommonUser. Common user has many Events. Event belongs to Common User.

So Event has a foreignKey called commonUserId.

How do I get the id of the user and use that when doing the insert?

I would have thought this would be automatic as part of the process as far as setting up relationships is concerned? Is that incorrect?

Also to complicate matters I have an Event Look-Up table (i will worry about this next so don't feel obligated to dive to deep) because Event also hasAndBelongsToMany through Event Lookup.

User

{
  "name": "CommonUser",
  "base": "User",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {},
  "validations": [],
  "relations": {
    "events": {
      "type": "hasMany",
      "model": "Event",
      "foreignKey": "eventId",
      "through": "EventLookUp"
    },
    "friends": {
      "type": "hasMany",
      "model": "CommonUser",
      "through": "Friend",
      "foreignKey": "friendId"
    }
  },
  "acls": [],
  "methods": {}
}

User

Event

{
  "name": "Event",
  "base": "PersistedModel",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {
    "name": {
      "type": "string"
    },
    "radius": {
      "type": "number",
      "default": 50
    },
    "status": {
      "type": "number"
    },
    "location": {
      "type": "geopoint",
      "required": true
    }
  },
  "validations": [],
  "relations": {
    "owner": {
      "type": "belongsTo",
      "model": "CommonUser",
      "foreignKey": "commonUserId"
    },
    "commonUsers": {
      "type": "hasAndBelongsToMany",
      "model": "CommonUser",
      "foreignKey": "ownerId",
      "through": "EventLookUp"
    },
    "galleries": {
      "type": "hasOne",
      "model": "Gallery",
      "foreignKey": ""
    },
    "photos": {
      "type": "hasMany",
      "model": "Photo",
      "foreignKey": "",
      "through": "Gallery"
    }
  },
  "acls": [],
  "methods": {}
}

Event

Event Lookup

{
  "name": "EventLookUp",
  "base": "PersistedModel",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {},
  "validations": [],
  "relations": {},
  "acls": [],
  "methods": {}
}

Event LookUp

If I can be pointed in the right direction that would be fantastic. It's hard to find an answer reading through the documentation. I think I need to use an operation hook before insert and set the Event Models properties? What is loopback's best practice as far as this goes?


Solution

  • In loopback swagger when you login as a user using loopback's default users/login api , you get access token object as response.You can copy the id of access token and paste into the box in top right corner in swagger and set the access token.Thus internally your accesstoken is set in loopback and for your every request from swagger, loopback append the access token along with the request.In this way you can get the access token from ctx(context) in remote methods.

    For create, findOrCreate, save an event obj:

    Event.observe('before save', function updateUserId(ctx, next) {
    
      let userId = ctx.options.accessToken.userId;`
    
      if (ctx.instance) {
        ctx.instance.commonUserId = userId;
      }
      next();
    });
    

    For updateAttributes for event obj:

    Event.observe('before save', function updateUserId(ctx, next) { 
    
      let userId = ctx.options.accessToken.userId; 
    
      if (ctx.currentInstance) { 
        ctx.currentInstance.commonUserId = userId;
      } 
      next(); 
    });