Build a blog with Areto Node.js framework

Photo controller

The PhotoController class defines a controller of the photo model.

module/admin/controller/PhotoController.js

const Base = require('../component/CrudController');
module.exports = class PhotoController extends Base {

  static getConstants () {
    return {
      METHODS: {
        'assign-main': ['post']
      }
    };
  }
};
module.exports.init(module);
const async = require('areto/helper/AsyncHelper');
const Article = require('../model/Article');
const File = require('../model/File');
const Photo = require('../model/Photo');
Create photo

The actionCreate method creates a photo model. The async.series array of asynchronous methods receives data to select one article of the list (Article.findToSelect). You can assign a photo to it.

module/admin/controller/PhotoController.js

actionCreate () {
  let model = new Photo;
  model.scenario = 'create';
  async.waterfall([
    cb => async.series({
      articles: cb => Article.findToSelect().all(cb)
    }, cb),
    (params, cb)=> {
      params.model = model;
      if (this.isGet()) {
        return this.render('create', params);
      }
      async.series([
        cb => model.load(this.getBodyParams()).save(cb),
        cb => model.isNew()
          ? this.render('create', params)
          : this.backToRef()
      ], cb);
    }
  ], err => this.throwError(err));
}
View uploaded photo

The actionView method calls the parent to get the necessary relations.

module/admin/controller/PhotoController.js

actionView () {
  super.actionView({
    with: ['article']
  });
}
Update photo

The actionUpload method uploads a file to the server. If the file is validated, a photo model will be created. Initial model is not linked to any article.

module/admin/controller/PhotoController.js

actionUpload () {
  let file = new File, photo;
  async.series([
    cb => file.upload(this, cb),
    cb => file.hasError()
      ? this.sendText(this.translate(file.getFirstError()), 400)
      : cb(),
    cb => {
      photo = new Photo;
      photo.set('file', file.getId());
      photo.validate(cb, ['file']);
    },
    cb => photo.hasError()
      ? this.sendText(this.translate(photo.getFirstError()), 400)
      : this.sendText(file.getId())
  ], err => this.throwError(err));
}

The actionAssignMain method sets the main photo of the article. The forceSave function saves article without any data validation. If the photo is not related to any article, then set flash error messages (one-off message to a user session), and user will be redirected to the viewing page.

module/admin/controller/PhotoController.js

actionAssignMain () {
  this.getModel({
    with: ['article']
  }, model => {
    let article = model.get('article');
    if (!article) {
      this.setFlash('danger', 'Article not found');
      return this.redirect(['view', model]);
    }
    article.set('mainPhotoId', model.getId());
    async.series([
      cb => article.forceSave(cb),
      cb => this.redirect(['article/view', article])
    ], err => this.throwError(err));
  });
}