Skip to content
This repository was archived by the owner on Feb 21, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions app/Helpers/ModelEnum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { DecoratorFn, LucidModel } from '@ioc:Adonis/Lucid/Orm'
// import { column as originalColumn } from '@ioc:Adonis/Lucid/Orm'

export type EnumDecorator = () => DecoratorFn

export const enumColumn: EnumDecorator = () => {
return function decorateAsColumn(target, property) {
const Model = target.constuctor as LucidModel
Model.boot()
Model.$addColumn(property, {
prepare: (value: string[]): string => `{${value.join(',')}}`,
consume: (value: string): string[] => value.slice(1, -1).split(','),
})
}
}

// declare module '@ioc:Adonis/Lucid/Orm' {
// export const column: typeof originalColumn & { enum: EnumDecorator }
// }

// column.enum = enumColumn
21 changes: 21 additions & 0 deletions app/Helpers/ModelJson.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { DecoratorFn, LucidModel } from '@ioc:Adonis/Lucid/Orm'
// import { column as originalColumn } from '@ioc:Adonis/Lucid/Orm'

export type JsonDecorator = () => DecoratorFn

export const jsonColumn: JsonDecorator = () => {
return function decorateAsColumn(target, property) {
const Model = target.constuctor as LucidModel
Model.boot()
Model.$addColumn(property, {
prepare: (value: {}): string => JSON.stringify(value),
consume: (value: string): {} => JSON.parse(value),
})
}
}

// declare module '@ioc:Adonis/Lucid/Orm' {
// export const column: typeof originalColumn & { json: JsonDecorator }
// }

// column.json = jsonColumn
27 changes: 27 additions & 0 deletions app/Models/Member.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { DateTime } from 'luxon'
import { BaseModel, BelongsTo, belongsTo, column } from '@ioc:Adonis/Lucid/Orm'
import User from './User'
import { enumColumn } from 'App/Helpers/ModelEnum'
import School from './School'

export type MemberRole = 'student' | 'teacher' | 'parent' | 'staff'

export default class Member extends BaseModel {
@column({ isPrimary: true })
public id: number

@belongsTo(() => User)
public user: BelongsTo<typeof User>

@belongsTo(() => School)
public school: BelongsTo<typeof School>

@enumColumn()
public roles: MemberRole[]

@column.dateTime({ autoCreate: true })
public createdAt: DateTime

@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
}
42 changes: 42 additions & 0 deletions app/Models/School.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { DateTime } from 'luxon'
import { BaseModel, column, HasMany, hasMany } from '@ioc:Adonis/Lucid/Orm'
import { jsonColumn } from 'App/Helpers/ModelJson'
import Member from './Member'

export type SchoolContact = {
email: string
phone: string
}

export type SchoolAddress = {
street: string
city: string
state: string
zip: string
}

export default class School extends BaseModel {
@column({ isPrimary: true })
public id: number

@column()
public name: string

@jsonColumn()
public contact: SchoolContact
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be better to have another model for the contact information with a relation to the school (hasOne + belongsTo)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was too lazy I have to admit 😅 I will do this thx


@jsonColumn()
public address: SchoolAddress
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same - it would be better to have another model for the adress with a relation to the school (hasOne + belongsTo)


@column()
public identifier: string

@column.dateTime({ autoCreate: true })
public createdAt: DateTime

@hasMany(() => Member, { foreignKey: 'school_id' })
public members: HasMany<typeof Member>

@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
}
24 changes: 19 additions & 5 deletions app/Models/User.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
import { DateTime } from 'luxon'
import Hash from '@ioc:Adonis/Core/Hash'
import { column, beforeSave, BaseModel, hasMany, HasMany } from '@ioc:Adonis/Lucid/Orm'
import {
column,
beforeSave,
BaseModel,
hasMany,
HasMany,
hasOne,
HasOne,
} from '@ioc:Adonis/Lucid/Orm'
import Access from 'App/Models/Access'
import Member from './Member'
import { enumColumn } from 'App/Helpers/ModelEnum'
import UserDetail from './UserDetail'

export type UserRole = 'admin' | 'user' | 'developer'

Expand All @@ -24,15 +35,18 @@ export default class User extends BaseModel {
@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime

@column({
prepare: (value: string[]): string => `{${value.join(',')}}`,
consume: (value: string): string[] => value.slice(1, -1).split(','),
})
@enumColumn()
Comment thread
florian-lefebvre marked this conversation as resolved.
public roles: UserRole[]

@hasMany(() => Access, { foreignKey: 'user_id' })
public accesses: HasMany<typeof Access>

@hasMany(() => Member, { foreignKey: 'user_id' })
public members: HasMany<typeof Member>

@hasOne(() => UserDetail, { foreignKey: 'user_id' })
public detail: HasOne<typeof UserDetail>

@beforeSave()
public static async hashPassword(user: User) {
if (user.$dirty.password) {
Expand Down
28 changes: 28 additions & 0 deletions app/Models/UserDetail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { DateTime } from 'luxon'
import { BaseModel, belongsTo, BelongsTo, column, computed } from '@ioc:Adonis/Lucid/Orm'
import User from './User'

export default class UserDetail extends BaseModel {
@column({ isPrimary: true })
public id: number

@column()
public firstName: string

@column()
public lastName: string

@computed()
public get fullName() {
return `${this.firstName} ${this.lastName}`
}

@belongsTo(() => User)
public member: BelongsTo<typeof User>

@column.dateTime({ autoCreate: true })
public createdAt: DateTime

@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
}
27 changes: 27 additions & 0 deletions database/migrations/1666341836371_members.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import BaseSchema from '@ioc:Adonis/Lucid/Schema'

export default class extends BaseSchema {
protected tableName = 'members'

public async up() {
this.schema.raw("CREATE TYPE member_role AS ENUM('student', 'teacher', 'parent', 'staff')")

this.schema.createTable(this.tableName, (table) => {
table.increments('id')
table.integer('user_id').unsigned().references('users.id').onDelete('CASCADE')
table.integer('school_id').unsigned().references('schools.id').onDelete('CASCADE')
table.specificType('roles', 'member_role[]').notNullable()

/**
* Uses timestamptz for PostgreSQL and DATETIME2 for MSSQL
*/
table.timestamp('created_at', { useTz: true })
table.timestamp('updated_at', { useTz: true })
})
}

public async down() {
this.schema.dropTable(this.tableName)
this.schema.raw('DROP TYPE member_role')
}
}
24 changes: 24 additions & 0 deletions database/migrations/1666342630554_user_details.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import BaseSchema from '@ioc:Adonis/Lucid/Schema'

export default class extends BaseSchema {
protected tableName = 'user_details'

public async up() {
this.schema.createTable(this.tableName, (table) => {
table.increments('id')
table.integer('user_id').unsigned().references('users.id').onDelete('CASCADE')
table.string('first_name', 32).notNullable()
table.string('last_name', 64).notNullable()

/**
* Uses timestamptz for PostgreSQL and DATETIME2 for MSSQL
*/
table.timestamp('created_at', { useTz: true })
table.timestamp('updated_at', { useTz: true })
})
}

public async down() {
this.schema.dropTable(this.tableName)
}
}
25 changes: 25 additions & 0 deletions database/migrations/1666347063115_schools.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import BaseSchema from '@ioc:Adonis/Lucid/Schema'

export default class extends BaseSchema {
protected tableName = 'schools'

public async up() {
this.schema.createTable(this.tableName, (table) => {
table.increments('id')
table.string('name', 255).notNullable()
table.json('contact').notNullable()
table.json('address').notNullable()
table.string('identifier').notNullable()

/**
* Uses timestamptz for PostgreSQL and DATETIME2 for MSSQL
*/
table.timestamp('created_at', { useTz: true })
table.timestamp('updated_at', { useTz: true })
})
}

public async down() {
this.schema.dropTable(this.tableName)
}
}