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

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

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

modules/admin/controllers/ArticleController.js

'use strict';
const Base = require('../components/CrudController');
module.exports = class ArticleController extends Base {

  getModelClass () {
    return require('../models/Article');
  }
};
module.exports.init(module);                                      
const ActiveDataProvider = require('areto/data/ActiveDataProvider');
Список статей

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

modules/admin/controllers/ArticleController.js

...
actionIndex () {
  let Class = this.getModelClass();
  let provider = new ActiveDataProvider({
    controller: this,
    query: Class.findBySearch(this.getQueryParam('search')).with('author', 'mainPhoto'),
    pagination: {},
    sort: {
      attrs: {
        [Class.PK]: true,
        status: true,
        title: true
      },
      defaultOrder: {
        [Class.PK]: -1
      }
    }
  });
  provider.prepare(err => {
    err ? this.throwError(err) : this.render('index', {provider});
  });
}
...
Просмотр статьи Просмотр статьи

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

modules/admin/controllers/ArticleController.js

...
actionView () {
  this.getModel(model => {
    let comments = new ActiveDataProvider({
      controller: this,
      query: model.relComments(),
      sort: {
        attrs: {
          [model.PK]: true
        },
        defaultOrder: {
          [model.PK]: -1
        }
      }
    });
    comments.prepare(err => {
      err ? this.throwError(err)
          : this.render('view', {model, comments});
    });
  }, ['author', 'photos', 'mainPhoto', 'tags']);
}
...
Создание статьи

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

modules/admin/controllers/ArticleController.js

...
actionCreate () {        
  let model = new (this.getModelClass());
  if (this.isPost()) {
    model.load(this.getBodyParams());
    model.set('authorId', this.user.getId());
    model.save(err => {
      if (err) {
        this.throwError(err);
      } else if (model.isNewRecord) {
        this.render('create', {model});
      } else {
        this.backToRef();
      }
    });            
  } else {
    this.render('create', {model});
  }
}
...
Редактирование статьи

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

modules/admin/controllers/ArticleController.js

...
actionUpdate () {        
  this.getModel(model => {
    this.user.can('updateArticle', (err, access)=>{
      if (err) {
        return this.throwError(err);
      }
      if (!access) {
        return this.throwForbidden();
      }
      if (this.isGet()) {
        return this.render('update', {model});
      }
      model.load(this.getBodyParams()).save(err => {
        if (err) {
          this.throwError(err);
        } else if (model.hasError()) {
          this.render('update', {model});
        } else {
          this.backToRef();
        }
      });
    }, { authorId: model.get('authorId') });
  }, 'photos', 'tags');
}
...