diff --git a/app/Models/Lesson.ts b/app/Models/Lesson.ts index 30e79b2..3fb3dbd 100644 --- a/app/Models/Lesson.ts +++ b/app/Models/Lesson.ts @@ -1,10 +1,21 @@ +/* eslint-disable import/no-cycle */ /* eslint-disable no-param-reassign */ import { DateTime } from 'luxon'; import { nanoid } from 'nanoid'; -import { BaseModel, beforeCreate, BelongsTo, belongsTo, column, HasOne, hasOne } from '@ioc:Adonis/Lucid/Orm'; +import { + BaseModel, + beforeCreate, + BelongsTo, + belongsTo, + column, + hasMany, + HasMany, + HasOne, + hasOne, +} from '@ioc:Adonis/Lucid/Orm'; import ColorHelper from 'App/Helpers/ColorHelper'; import Course from './Course'; -// eslint-disable-next-line import/no-cycle +import LessonMaterial from './LessonMaterial'; import LessonContent from './LessonContent'; import Color from './Color'; @@ -45,6 +56,9 @@ export default class Lesson extends BaseModel { }) public content: HasOne; + @hasMany(() => LessonMaterial, { foreignKey: 'lesson_id' }) + public materials: HasMany; + @column.dateTime({ autoCreate: true }) public createdAt: DateTime; @@ -68,4 +82,13 @@ export default class Lesson extends BaseModel { course.color_id = color.id; } } + + /** + * Serialize the `$extras` object + */ + public serializeExtras() { + return { + materials_count: this.$extras.materials_count, + }; + } } diff --git a/app/Models/LessonContent.ts b/app/Models/LessonContent.ts index 70e0cc2..5a1edd1 100644 --- a/app/Models/LessonContent.ts +++ b/app/Models/LessonContent.ts @@ -1,8 +1,7 @@ /* eslint-disable import/no-cycle */ -import { BaseModel, BelongsTo, belongsTo, column, HasMany, hasMany } from '@ioc:Adonis/Lucid/Orm'; +import { BaseModel, BelongsTo, belongsTo, column } from '@ioc:Adonis/Lucid/Orm'; import { DateTime } from 'luxon'; import Lesson from './Lesson'; -import LessonMaterial from './LessonMaterial'; export default class LessonContent extends BaseModel { @column({ isPrimary: true }) @@ -14,9 +13,6 @@ export default class LessonContent extends BaseModel { @column() public video_url: string; - @hasMany(() => LessonMaterial, { foreignKey: 'lesson_content_id' }) - public materials: HasMany; - @belongsTo(() => Lesson, { foreignKey: 'lesson_id' }) public lesson: BelongsTo; diff --git a/app/Models/LessonMaterial.ts b/app/Models/LessonMaterial.ts index ea75db8..44c3db5 100644 --- a/app/Models/LessonMaterial.ts +++ b/app/Models/LessonMaterial.ts @@ -1,7 +1,7 @@ +/* eslint-disable import/no-cycle */ import { BaseModel, BelongsTo, belongsTo, column } from '@ioc:Adonis/Lucid/Orm'; import { DateTime } from 'luxon'; -// eslint-disable-next-line import/no-cycle -import LessonContent from './LessonContent'; +import Lesson from './Lesson'; export default class LessonMaterial extends BaseModel { @column({ isPrimary: true }) @@ -20,12 +20,12 @@ export default class LessonMaterial extends BaseModel { public ext: string; @column() - public lesson_content_id: number; + public lesson_id: string; - @belongsTo(() => LessonContent, { - foreignKey: 'lesson_content_id', + @belongsTo(() => Lesson, { + foreignKey: 'lesson_id', }) - public content: BelongsTo; + public lesson: BelongsTo; @column.dateTime({ autoCreate: true }) public createdAt: DateTime; diff --git a/app/Models/User.ts b/app/Models/User.ts index 08209b5..4eb9bae 100644 --- a/app/Models/User.ts +++ b/app/Models/User.ts @@ -62,10 +62,10 @@ export default class User extends BaseModel { }) public likes: ManyToMany; - @column.dateTime({ autoCreate: true, serializeAs: null }) + @column.dateTime({ autoCreate: true }) public createdAt: DateTime; - @column.dateTime({ autoCreate: true, autoUpdate: true, serializeAs: null }) + @column.dateTime({ autoCreate: true, autoUpdate: true }) public updatedAt: DateTime; /** diff --git a/app/Repositories/CourseRepository.ts b/app/Repositories/CourseRepository.ts index 28fb993..3d2ed62 100644 --- a/app/Repositories/CourseRepository.ts +++ b/app/Repositories/CourseRepository.ts @@ -82,7 +82,7 @@ export default class CourseRepository { .preload('teacher') .preload('color') .preload('category') - .preload('lessons', q => q.preload('color').orderBy('display_order', 'asc')) + .preload('lessons', q => q.preload('color').orderBy('display_order', 'asc').withCount('materials')) .preload('students') .where('id', id) .first(); diff --git a/app/Repositories/LessonRepository.ts b/app/Repositories/LessonRepository.ts index abd7ab5..9fc4fd6 100644 --- a/app/Repositories/LessonRepository.ts +++ b/app/Repositories/LessonRepository.ts @@ -89,7 +89,7 @@ export default class LessonRepository { /** * Create content and materials fields in database */ - const content = await lesson.related('content').create({ video_url: data.video_url }); + await lesson.related('content').create({ video_url: data.video_url }); if (data.materials) { await Promise.all( @@ -100,7 +100,7 @@ export default class LessonRepository { await file.moveToDisk('materials'); if (file.state === 'moved') { const url = await Drive.getUrl(`materials/${file.fileName}`); - await content.related('materials').create({ + await lesson.related('materials').create({ name: file.fileName, clientName: file.clientName, ext: file.extname, @@ -114,7 +114,7 @@ export default class LessonRepository { /** * Load data */ - await lesson.load('content', q => q.preload('materials')); + await lesson.load(loader => loader.load('content').load('materials')); return lesson; } diff --git a/app/Services/LessonService.ts b/app/Services/LessonService.ts index 7a39a07..dcba84c 100644 --- a/app/Services/LessonService.ts +++ b/app/Services/LessonService.ts @@ -101,12 +101,9 @@ export default class LessonService { /** * Allow user to view lesson material */ - await material.load('content', q => q.preload('lesson')); + await material.load('lesson'); - const { - content: { lesson }, - } = material; - if (await ctx.bouncer.denies('viewLessonContent', lesson)) { + if (await ctx.bouncer.denies('viewLessonContent', material.lesson)) { return { success: false, status: HttpStatusEnum.FORBIDDEN, @@ -254,9 +251,9 @@ export default class LessonService { } /** - * Load lesson content with materials + * Load lesson with materials */ - await lesson.load('content', q => q.preload('materials')); + await lesson.load(loader => loader.load('content').load('materials')); return { success: true, diff --git a/app/Validators/Contacts/UpdateContactsValidator.ts b/app/Validators/Contacts/UpdateContactsValidator.ts index ff3c965..adb087a 100644 --- a/app/Validators/Contacts/UpdateContactsValidator.ts +++ b/app/Validators/Contacts/UpdateContactsValidator.ts @@ -10,6 +10,7 @@ export default class UpdateContactsValidator { locales: ['ru-RU', 'en-US'], strict: true, }), + // TODO validate correctly rules.unique({ table: 'contacts', column: 'phone_number' }), ]), vk_id: schema.string.optional({}, [rules.regex(/^([a-zA-Z0-9_]){1,64}$/)]), diff --git a/database/migrations/1637080400230_lesson_materials.ts b/database/migrations/1637080400230_lesson_materials.ts index 90b82a3..56ddb25 100644 --- a/database/migrations/1637080400230_lesson_materials.ts +++ b/database/migrations/1637080400230_lesson_materials.ts @@ -10,7 +10,7 @@ export default class LessonMaterials extends BaseSchema { table.string('name').notNullable(); table.string('client_name').notNullable(); table.string('ext').notNullable(); - table.integer('lesson_content_id').unsigned().references('lesson_contents.id').onDelete('CASCADE'); + table.string('lesson_id', 21).unsigned().references('lessons.id').onDelete('CASCADE'); table.timestamp('created_at', { useTz: true }); table.timestamp('updated_at', { useTz: true }); });