Skip to content

Default values for extra fields of through-relations #649

@mattiloh

Description

@mattiloh

First of all: thanks for this great library. It's really a pleasure to work with it! ❤️

Now to my question: We use join-tables to define access-levels between users and resources. This join table contains a scope field, which defines a user's access level (e.g. owner, editor etc.). On the resources itself, we define each group of users as separate relations (owners, editors etc.). This might seem cumbersome, but it simplifies data handling with normalized stores on the frontend a lot.

Here's a quick example, how these relations look like:

class Project extends Model {
  static get tableName() {
    return 'projects';
  }

  static get relationMappings() {
    return {
      owners: {
        relation: Model.ManyToManyRelation,
        modelClass: `${__dirname}/user`,
        join: {
          from: 'projects.id',
          through: {
            from: 'projects_users.project_id',
            to: 'projects_users.user_id',
            extra: ['scope'],
          },
          to: 'users.id',
        },
        filter: qb => qb.where('projects_users.scope', 'owner'),
      },
      editors: {
        relation: Model.ManyToManyRelation,
        modelClass: `${__dirname}/user`,
        join: {
          from: 'projects.id',
          through: {
            from: 'projects_users.project_id',
            to: 'projects_users.user_id',
            extra: ['scope'],
          },
          to: 'users.id',
        },
        filter: qb => qb.where('projects_users.scope', 'editor'),
      },
    };
  }
}

Thanks to filter, it's really easy to define those relations and fetch the specific user-groups from the database. But when it comes to adding new users to a group like

await project
    .$relatedQuery('owners')
    .relate(userId)

it doesn't set the scope field to owners:

insert into "projects_users" ("project_id", "user_id") values (?, ?)

What I need, is a way to define default values for the field scope within the relation mapping. Do you know a way to do that?

I could imagine to extend the extra field API to something like

{
  editors: {
    relation: Model.ManyToManyRelation,
    modelClass: `${__dirname}/user`,
    join: {
      from: 'projects.id',
      through: {
        from: 'projects_users.project_id',
        to: 'projects_users.user_id',
        extra: [{
            column: 'scope',
            alias: 'customPropertyName',
            onInsert: value => value || 'owner',
          },
        }],
      },
      to: 'users.id',
    },
    filter: qb => qb.where('projects_users.scope', 'editor'),
  },
}

Any thoughts on that? Do you think that's feasible? I would like to try a PR, if it's considered a valuable addition and there's no other way to solve it.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions