Build a blog with Areto Node.js framework

Photo model

This class inherited from the Photo of the blog's frontend.

Photo model

The photo model contains three attributes. The first attr is the title containing the description of the photo. The second attr is the name of the image file. The third attr is a link to the article, which owns the photo.

Images from users can be large and have different types. There is no need to store files in the original state. Therefore, images will be converted into a common format. To do this, use the ImageConverterbehavior. Its incoming data is the File model describing uploaded file. The size property of the behavior defines the maximum height or width of the picture scale.

In addition to the full image, you need to display previews of various sizes. The best way is to create separate files for each thumb size. Use the neededThumbs property that contains a list of the required dimensions.

To protect the copyright, or create unique photos, use a watermark. It will automatically be applied to each image. Set the image size and the corresponding watermark file int the watermark property.

Files can be given for a direct link as static resources or only after verification of access rights. In the case of restricted access converted clear images are placed in a private part of the website (storeDir: path.join(__dirname, '../uploads/photos')). These sources are available in the admin module only. But all watermarked thumbnails placed in the frontend resources (thumbDir: path.join(__dirname, '../../../web/photos')).

The filenameAttr property defines the model attribute that stores the file name.

modules/admin/models/Photo.js

'use strict';
const Base = require('../../../models/Photo');
const path = require('path');

module.exports = class Photo extends Base {  
  static getConstants () {
    return {
      TABLE: 'photo',
      STORED_ATTRS: ['title', 'filename', 'articleId'],
      RULES: [
        ['title', 'string', {min: 3, max: 255}],
        ['file', 'required', {on: ['create']}],
        ['file', 'file', {onlyImage: true}],
        ['articleId', 'filter', {filter: 'ObjectId'}],
        ['articleId', 'exist', {
          targetClass: require('./Article'),
          targetAttr: this.PK
        }]
      ],
      BEHAVIORS: {
        photo: {
          Class: require('../components/behaviors/ImageConverter'),
          FileClass: require('./File'),
          filenameAttr: 'filename',
          storeDir: path.join(__dirname, '../uploads/photos'),
          thumbDir: path.join(__dirname, '../../../web/photos'),
          size: 720,
          neededThumbs: [720, 360, 128],
          watermark: {
            720: path.join(__dirname, '../data/photo-watermark.png')
          }
        }
      }
    };
  }
};
module.exports.init(module);       
const Article = require('./Article');

The relArticle relation finds article related to a photo.

modules/admin/models/Photo.js

...
relArticle () {
  return this.hasOne(Article, [Article.PK, 'articleId']);
}
...