Как добавить метод экземпляра ко всем моделям в sails.js?

Я хотел бы добавить функцию по умолчанию toDisplay ко всем моделям, которые будут использовать метаданные, не похожие на определения атрибутов/ассоциаций, для выполнения манипуляций с атрибутами/ассоциациями экземпляра, что делает их подходящими для отображения в пользовательском интерфейсе.

например:

Foo.findOne(someId)
  .exec(function(err, foo) {
    ...
    res.view({
      foo: foo.toDisplay(),
    });
  });

Ответ 1

Конфигурация модели полностью документирована здесь, на SailsJS.org. @umassthrower прав, указав, что добавление метода экземпляра в config/models.js добавит его ко всем вашим моделям; он также правильно заметил, что это не намеренное использование конфигурационного файла.

Причина, по которой вы обнаруживаете, что это немного сложнее в Sails, чем Rails, заключается в том, что Ruby имеет реальные классы и наследование, а Javascript имеет только объекты. Один довольно чистый способ имитации наследования и расширения ваших объектов модели из "базового" объекта - это использовать что-то вроде Lodash _.merge function. Например, вы можете сохранить базовую модель в lib/BaseModel.js:

// lib/BaseModel.js
module.exports = {

  attributes: {

    someAttribute: 'string',

    someInstanceFunction: function() {
      // do some amazing (synchronous) calculation here
    }

  }

};

Затем в файле модели требуется lodash и используйте _.extend:

// api/models/MyModel.js
var _ = require('lodash');
var BaseModel = require("../../lib/BaseModel.js");
module.exports = _.merge({}, BaseModel, {

  attributes: {

    someOtherAttribute: 'integer'

  }

};

Атрибуты вашей базовой модели будут объединены с MyModel, причем MyModel имеет приоритет.

Установка первого аргумента пустой модели {} здесь важна; _.merge является разрушительным для первого отправленного объекта, поэтому, если вы только что сделали _.merge(BaseModel, {...}, базовая модель будет изменена.

Кроме того, запомните npm install lodash!

Ответ 2

Это можно сделать, добавив свою функцию к вашим атрибутам модели, например:

module.exports = {
    attributes: {
        attribute1: {
            type: String
        },
        attribute2: {
            type: String
        },
        toDisplay: function () {
            // your function here
        }

        // You can also override model functions like .toJSON or .toObject
        toJSON: function () {
            // your custom JSON here
        }
    }
}

В разделе Парусная документация для моделей в разделе "Методы атрибутов". Стоит отметить, что в зависимости от того, что вы делаете, вам может не понадобиться метод toDisplay(); вы можете просто переопределить метод toJSON(), если вы только пытаетесь отформатировать любой вывод или удалить любую конфиденциальную информацию.