Build a blog with Areto Node.js framework

CRUD controller

Administrative actions (create, view, update, delete) with objects of different classes are repeated from one controller to another and can be assembled in the single base class.

modules/admin/components/CrudController.js

'use strict';
const Base = require('./Controller');
module.exports = class CrudController extends Base {
  // place methods here
};

The actionCreate method is responsible for creating a new instance of the class derived from the getModelClass. The create scenario, filtering validation rules, used to create a model.

GET request renders empty model form. POST request loads attribute values, checks and if successful stores a new object. If the validation fails, then the form is filled with obtained values and found errors. After saving the action redirects to the referral page.

modules/admin/components/CrudController.js

...
actionCreate () {
  let model = new (this.getModelClass());
  model.scenario = 'create';
  if (this.isPost()) {
    model.load(this.getBodyParams()).save(err => {
      if (err) {
        this.throwError(err);
      } else if (model.hasError()) {
        this.render('create', {model});
      } else {
        this.backToRef();
      }
    });
  } else {
    this.render('create', {model});
  }
}
...

The actionView method displays a model. It can be overridden by the target controller to load a model together with relations.

modules/admin/components/CrudController.js

...
actionView (...relations) {
  this.getModel(model => {
    this.render('view', {model});
  }, relations);
}
...

The actionUpdate, actionCreate methods differ validation scenario. Furthermore, the actionUpdate method loads a model to update.

modules/admin/components/CrudController.js

...
actionUpdate (...relations) {
  this.getModel(model => {
    model.scenario = 'update';
    if (this.isPost()) {
      model.load(this.getBodyParams()).save(err => {
        if (err) {
          this.throwError(err);
        } else if (model.hasError()) {
          this.render('update', {model});
        } else {
          this.backToRef();
        }
      });
    } else {
      this.render('update', {model});
    }  
  }, relations);
}
...

The actionDelete method removes a model with identifier obtained from the GET request. If AJAX request has been received, then, after removal, the response will contain the identifier of the deleted object. Otherwise, there will redirect to the previous page.

modules/admin/components/CrudController.js

...
actionDelete () {
  this.getModel(model => {
    model.remove(err => {
      if (err) {
        this.throwError();
      } else if (this.isAjax()) {
        this.send(model.getId());  
      } else {
        this.backToRef();
      }
    });
  });
}
...