---
# System prepended metadata

title: Sequelize 自牽關聯實做父子節點/樹

---

# Sequelize 自牽關聯實做父子節點/樹
##### `feathersjsv4` `nodejs` `sequelize`
```javascript=
// See http://docs.sequelizejs.com/en/latest/docs/models-definition/
// for more of what you can do here.
const Sequelize = require('sequelize');
const DataTypes = Sequelize.DataTypes;
const { COLUMN } = require('../utils/constant');

module.exports = function (app) {
  const sequelizeClient = app.get('sequelizeClient');
  const node = sequelizeClient.define('node', {
    [COLUMN.ID]: {
      type: DataTypes.STRING,
      primaryKey: true,
      allowNull: false,
      unique: true,
    },
    parent_id: {
      type: DataTypes.STRING,
      allowNull: true,
    }
  }, {
    hooks: {
      beforeCount(options) {
        options.raw = true;
      }
    }
  });

  // eslint-disable-next-line no-unused-vars
  node.associate = function (models) {
    node.belongsTo(models.node, {
      as: 'parent',
      foreignKey: 'parent_id',
    });

    node.hasMany(models.node, {
      as: 'children',
      foreignKey: 'parent_id',
    });
  };

  return node;
};

```
#### 查找父子節點
- 這裡，as: 'parent' 選項告訴 Sequelize 這個關聯的名稱是 'parent'。因此，Sequelize 會為每個 Node 實例生成一個 getParent() 方法，用於獲取該節點的父節點。同樣地，它也會生成一個 setParent() 方法，用於設置該節點的父節點；getChildren() 方法，用於獲取該節點的子節點。同樣地，它也會生成一個 setChildren() 方法，用於設置該節點的子節點
```javascript=
const sequelizeClient = app.get('sequelizeClient');
const Node = sequelizeClient.models.node;
const node = await Node.findByPk('819f60c1-af16-4bce-9b74-61b0ce1f841f');
const parentNode = await node.getParent();
console.log(parentNode);
const childNode = await node.getChildren();
console.log(childNode);
const nodes = await Node.findAll({
  include: [
    { model: Node, as: 'parent', attributes: ['id', 'parent_id'] }, // 包含父節點
    { model: Node, as: 'children', attributes: ['id', 'parent_id'] }, // 包含子節點
  ],
  raw: true,
  nest: true,
});
         
console.log(nodes);
```