Строим блог на 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, Object.assign({
      categories: await 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 = Article.findBySearch(this.getQueryParam('search')).with('author', 'mainPhoto');
  let provider = this.createDataProvider({
    query,
    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 = new Article;
  if (this.isGet()) {
    return this.renderForm('create', {model});
  }
  model.load(this.getBodyParams());
  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) {
    this.throwForbidden();
  }
  this.isPost() && await model.load(this.getBodyParams()).save()
    ? this.backToRef()
    : await this.renderForm('update', {model});
}<