Строим блог на Areto фреймворк

Контроллер статей

Класс ArticleController отвечает за действия с моделью статьи.

module/admin/controllers/ArticleController.js

const Base = require('../component/CrudController');

module.exports = class ArticleController extends Base {

  async renderForm (template, params) {
    await this.render(template, {
      categories: await this.spawn(Category).findNames().all(),
      ...params
    });
  }
};
module.exports.init(module);

const Category = require('../model/Category');
const Article = require('../model/Article');<
Список статей

Метод actionIndex выводит список статей с возможностью поиска и сортировки по идентификатору, статусу и заголовку. Каждая статья извлекается вместе со связанными моделями author и mainPhoto, которые необходимы для представления статьи в списке.

module/admin/controllers/ArticleController.js

async actionIndex () {
  let searchText = this.getQueryParam('search');
  let query = this.spawn(Article).findBySearch(this.getQueryParam('search')).with('author', 'mainPhoto');
  let provider = this.createDataProvider({
    query: this.spawn(Article).findBySearch(searchText).with('author', 'mainPhoto'),
    pagination: {pageSize: 10},
    sort: {
      attrs: {
        [Article.PK]: true,
        status: true,
        title: true
      },
      defaultOrder: {[Article.PK]: -1}
    }
  });
  await this.renderDataProvider(provider, 'index', {provider, searchText});
}<
Просмотр статьи Просмотр статьи

Метод actionView выводит объект статьи на просмотр. Вместе с ним загружаются все связанные модели author, photos, mainPhoto, tags. Из отношения relComments, через провайдер данных, формируется постраничный список комментариев, относящихся к статье.

module/admin/controllers/ArticleController.js

async actionView () {
  let model = await this.getModel({
    with: ['author', 'category', 'photos', 'mainPhoto', 'tags']
  });
  let comments = this.createDataProvider({
    query: model.relComments(),
    sort: {
      attrs: {
        [model.PK]: true
      },
      defaultOrder: {[model.PK]: -1}
    }
  });
  await this.renderDataProvider(comments, 'view', {model, comments});
}<
Создание статьи

Метод actionCreate отвечает за действие по созданию новой статьи. Атрибут authorId, отвечающий за автора статьи, устанавливается по текущему пользователю.

module/admin/controllers/ArticleController.js

actionCreate () {
  let model = this.spawn(Article);
  if (this.isGet()) {
    return this.renderForm('create', {model});
  }
  model.load(this.getPostParams());
  model.set('authorId', this.user.getId());
  await model.save()
    ? this.backToRef()
    : await this.renderForm('create', {model});
}<
Редактирование статьи

Метод actionUpdate отвечает за действие по редактированию статьи. После того как статья найдена, проверяется разрешение для текущего пользователя. В асинхронный метод can последним аргументом передаются параметры, используемые для инициализации бизнес-правила доступа.

module/admin/controllers/ArticleController.js

actionUpdate () {
  let model = await this.getModel({with: ['photos', 'tags']});
  let access = await this.user.can('updateArticle', {authorId: model.get('authorId')});
  if (!access) {
    throw new Forbidden;
  }
  return this.isPost() && await model.load(this.getPostParams()).save()
    ? this.backToRef()
    : this.renderForm('update', {model});
}<