Data Structure for Multiple User Types

My app requires several user types which are not mutually exclusive. Thus, a user could be 2 or more different types. Plus, there are different fields associated with the different user types. So my question is as follows…

Would it be best to create all possible fields on the existing User object and then display only the relevant ones in the UI based on the context; OR would it be better to create a “thing” for each user type, which has only the relevant fields for that user type?

8 Likes

The latter. The way you differentiate between the user types is typically called a “Role”. So you make a Role data type. Now make some Roles. Only you, the admin make these.

Then you make a field “Roles” of data type Role on the User. Since your Users seem to need to be of multiple types, you make that a field a list (click the checkbox). So now your User objects have a list of Roles on them. (a_User’s Roles returns a list of Role type representing the Roles that User has). This list is, of course, initially empty.

To give a User a Role, you attach a Role to their Roles list. (Make changes to a thing… what thing? User. What field? Roles add Do a search for Role (constraint: whatever Role you need).)

Then, across your app you just do whatever you need to do if a User has some certain Role.

3 Likes

I would encourage you to go with the former. I’d create a user type called User Category (for each type of user) and if you find you have considerable differences in user categories (lets call them attributes), you could group these attributes into their own data thing called User Attribute or something like that. So you’d end up with something like the following:

3 Data Types:

  • User Category
  • User Attribute
  • User

User Category Type would have the following fields:

  • Name (text)
  • Description (text) - optional
  • User List (type = User - List)
  • Attribute List (type = User Category Attribute - List)

Your User Attribute Type would have the following fields:

  • Attribute Name (text)
  • Description (text) - optional
  • User Category - List (type = User Category - List) assuming one attribute can belong to more than one category

Then finally, within your User Type you’d have just add the:

  • User Category (type = User Category) unless one user could belong to more than one Category, in which case you’d make this field a List type.

This structure of using lists in bubble data tables took me a little bit to get my head around at first but is super important once you start adding complexity to your app.

Good luck,

BM

2 Likes

upon re-read i think my recommendation (as well as Keith’s) sits somewhere between your former and latter description in the question

IThere’s a bunch of different ways to do this, but the point is you CANNOT create a parallel User type so do not think about it this way (the former approach).

You can turn my idea on its head: a Role can be a thing where you create a thing whenever you want to assign a User to a role.

For example, say you have a Manager role. Create a datatype called Manager. Manager doesn’t need any fields on it!

To make someone a Manager, you just create a new Manager thing (in an on page workflow). Now a User is a Manager if Do a Search for Managers’s Creator contains that User.

(If you have a need to create Managers in a purely server-side workflow, Manager must have a field of User type on it as a Manager Created this way will have no Created By. You could call that field Member or something. Then a User is a Manager if Do a Search for Managers’s Member contains User.

I think this is funny.)

lol. I read the ‘latter’ option as a separate table for each group of users - which obviously can’t be done… I think we have sufficiently bamboozled him now :slight_smile:

Well, there are a lot of ways. My main point is DO NOT think about roles as a bunch of booleans or a list of texts on the user. They need to be easily extensible and maintainable. They need to be a datatype.

The “how” of this kind of comes down to how such roles need to be assigned. (My first suggestion is good for when role is self selectable as that technique lends itself to making a dropdown. The second method is good for system-type roles like “Administrator” (My approach there described in another post about how I make myself an admin in my apps and why it’s super secure.)

@keith and @brett.miles, thanks for the input! You’ve helped greatly with my thought process. At this point, I’m thinking perhaps a hybrid approach might work well.

There are exactly 4 user types/roles, so instead of a list of roles on the User table, I’m thinking a field for each role will work. Then, a separate “thing” (table) for each role can be added, containing the relevant fields (attributes) for that role.

An empty role field on the User table means they don’t have that role. If it’s non-empty, then it simply references the record in the appropriate role table containing that user’s attributes for the role.

In the [very unlikely] event another role is needed, it would mean an additional field in the user table and an additional role table with the necessary attributes.

Any problems with that approach?

1 Like

Hey Brett, thanks for this post, super helpful.

Quick question - I’m trying to figure out the best way to link the attribute data storage for each user (stored at the user level) with the User Attribute data types. Right now, I just have matching text (e.g., “first name” is a field in Users, and a data entry in User Attributes), but there’s no formal link between the two. Do you know if there’s a better way to solve this? I haven’t seen a way in bubble to use a field from one data type and actually input that in the database for a different data type.

I’m in a similar situation right now, and would like to post how I’m structuring my data to A) get feedback and B) potentially help others.

I am creating an app that will have a back end “Salesperson” user type, and a front end “Client” type. There are fields specific to Salesperson and specific to Client, and except for a few generic fields like Name they don’t overlap. Lastly, within the Salesperson type there are admins and standard users.

I’m structuring the data this way:
Salesperson will be a Thing with fields for all data specific to Salesperson, and a User field
Client with be Thing with fields for all data specific to Client, and a User field
User will have a field for Salesperson, and a field for Client. The relevant one will be set to and instance of the Thing, with its fields filled out. e.g. A client registering will trigger creation of a Client with fields filled, User set to current user, and the User Client field set to the Client that just got created.

Seems like there should be a better way of explaining that, but I think you get the picture.

I considered the idea of just having one Roles Thing and an Attribute Thing for easy extension of roles and fields, but decided against it for my application.

@austinhughes703 I’m curious what you ended up going with and how it worked out for you.

Since it’s been a hot minute since you wrote this, do you still feel this structure is best? Also, would you mind helping a Bubble noob like me understand why this is helpful with more complex apps? I’d be super grateful!