feat: added colors to category model & added some helper funcs

This commit is contained in:
Sergey Yarkov 2021-11-21 20:51:26 +03:00
parent aae79b582b
commit 10f72f3090
12 changed files with 73 additions and 9 deletions

View File

@ -0,0 +1,10 @@
import Color from 'App/Models/Color';
import * as utils from 'App/Utils';
export default class ColorHelper {
public static async generateRandomColor(): Promise<Color | null> {
const colors = await Color.query();
if (colors.length === 0) return null;
return colors[utils.generateRandomInt({ min: 0, max: colors.length - 1 })];
}
}

View File

@ -2,7 +2,9 @@
/* eslint-disable import/no-cycle */
import { DateTime } from 'luxon';
import { nanoid } from 'nanoid';
import { BaseModel, beforeCreate, column } from '@ioc:Adonis/Lucid/Orm';
import { BaseModel, beforeCreate, belongsTo, BelongsTo, column } from '@ioc:Adonis/Lucid/Orm';
import ColorHelper from 'App/Helpers/ColorHelper';
import Color from './Color';
export default class Category extends BaseModel {
@column({ isPrimary: true })
@ -14,6 +16,14 @@ export default class Category extends BaseModel {
@column()
public description: string;
@column({ serializeAs: null })
public color_id: number | null;
@belongsTo(() => Color, {
foreignKey: 'color_id',
})
public color: BelongsTo<typeof Color>;
@column.dateTime({ autoCreate: true, serializeAs: null })
public createdAt: DateTime;
@ -28,4 +38,13 @@ export default class Category extends BaseModel {
public static assignCategoryId(category: Category) {
category.id = nanoid();
}
@beforeCreate()
public static async assignRandomColor(category: Category) {
const color = await ColorHelper.generateRandomColor();
if (color) {
category.color_id = color.id;
}
}
}

View File

@ -14,10 +14,12 @@ import {
manyToMany,
} from '@ioc:Adonis/Lucid/Orm';
import { attachment, AttachmentContract } from '@ioc:Adonis/Addons/AttachmentLite';
import ColorHelper from 'App/Helpers/ColorHelper';
import Category from 'App/Models/Category';
import Lesson from 'App/Models/Lesson';
import User from 'App/Models/User';
import CourseStatusEnum from 'App/Datatypes/Enums/CourseStatusEnum';
import Color from './Color';
export default class Course extends BaseModel {
@column({ isPrimary: true })
@ -38,6 +40,14 @@ export default class Course extends BaseModel {
@column({ serializeAs: null })
public category_id: string;
@column({ serializeAs: null })
public color_id: number | null;
@belongsTo(() => Color, {
foreignKey: 'color_id',
})
public color: BelongsTo<typeof Color>;
@column()
public status: CourseStatusEnum;
@ -86,6 +96,15 @@ export default class Course extends BaseModel {
course.id = nanoid();
}
@beforeCreate()
public static async assignRandomColor(course: Course) {
const color = await ColorHelper.generateRandomColor();
if (color) {
course.color_id = color.id;
}
}
/**
* Serialize the `$extras` object
*/

View File

@ -29,7 +29,7 @@ export default class Lesson extends BaseModel {
public course: BelongsTo<typeof Course>;
@column({ serializeAs: null })
public color_id: number;
public color_id: number | null;
@belongsTo(() => Color, {
foreignKey: 'color_id',

View File

@ -21,7 +21,7 @@ export default class CategoryRepository {
* @returns Array of categories
*/
public async getAll(): Promise<Category[]> {
const categories = await this.Category.query();
const categories = await this.Category.query().preload('color');
return categories;
}
@ -32,7 +32,7 @@ export default class CategoryRepository {
* @returns Category or null
*/
public async getById(id: string | number): Promise<Category | null> {
const category = await this.Category.query().where('id', id).first();
const category = await this.Category.query().preload('color').where('id', id).first();
return category;
}

View File

@ -61,7 +61,12 @@ export default class CourseRepository {
query.andWhere('status', status);
}
const courses = await query.preload('category').withCount('students').withCount('likes').withCount('lessons');
const courses = await query
.preload('color')
.preload('category')
.withCount('students')
.withCount('likes')
.withCount('lessons');
return courses;
}
@ -75,6 +80,7 @@ export default class CourseRepository {
public async getById(id: string | number): Promise<Course | null> {
const course = await this.Course.query()
.preload('teacher')
.preload('color')
.preload('category')
.preload('lessons', q => q.preload('color'))
.preload('students')
@ -192,6 +198,9 @@ export default class CourseRepository {
course.teacher_id = data.teacher_id;
course.category_id = data.category_id;
/**
* Attach image
*/
if (data.image) {
course.image = Attachment.fromFile(data.image);
}

View File

@ -45,7 +45,7 @@ export default class MeService {
*/
if (RoleHelper.userHasRoles(user.roles, [RoleEnum.STUDENT])) {
await user.load('courses', q => {
q.preload('category');
q.preload('category', loader => loader.preload('color'));
q.withCount('students');
q.withCount('likes');
q.withCount('lessons');

4
app/Utils/index.ts Normal file
View File

@ -0,0 +1,4 @@
// eslint-disable-next-line import/prefer-default-export
export const generateRandomInt = ({ min, max }: { min: number; max: number }): number => {
return Math.floor(Math.random() * (max - min + 1) + min);
};

View File

@ -1,4 +1,5 @@
import Factory from '@ioc:Adonis/Lucid/Factory';
import { string } from '@ioc:Adonis/Core/Helpers';
/**
* Datatypes
@ -21,7 +22,7 @@ const makeFakeUser = (faker: Faker.FakerStatic, loginPrefix?: string) => {
return {
first_name: faker.name.firstName(),
last_name: faker.name.lastName(),
login: `${loginPrefix || 'user'}${faker.datatype.number(10000)}`,
login: `${loginPrefix || 'user'}-${string.generateRandom(5)}`,
email: faker.internet.exampleEmail(),
password: '123456',
};

View File

@ -11,7 +11,7 @@ export default class Colors extends BaseSchema {
.enu('name', Object.keys(ColorEnum), {
useNative: true,
enumName: 'color_name_enum',
existingType: false,
existingType: true,
schemaName: 'public',
})
.notNullable();

View File

@ -8,6 +8,7 @@ export default class Categories extends BaseSchema {
table.string('id', 21).primary();
table.string('title').notNullable();
table.string('description');
table.integer('color_id').unsigned().references('colors.id');
table.timestamp('created_at', { useTz: true });
table.timestamp('updated_at', { useTz: true });
});

View File

@ -16,11 +16,12 @@ export default class Courses extends BaseSchema {
table.string('description').notNullable();
table.string('teacher_id', 21).unsigned().references('users.id').notNullable().onDelete('CASCADE');
table.string('category_id', 21).unsigned().references('categories.id').notNullable().onDelete('CASCADE');
table.integer('color_id').unsigned().references('colors.id');
table
.enu('status', Object.values(CourseStatusEnum), {
useNative: true,
enumName: 'course_status_enum',
existingType: false,
existingType: true,
schemaName: 'public',
})
.notNullable();