thinkjs文檔中model.relation寫法的探討

先說明,官方文檔中這種get方法的示例是徹底沒問題的

module.exports = class extends think.Model {
  // 配置關聯關係
  get relation() {
    return {
      cate: { // 配置跟分類的關聯關係
        type: think.Model.MANY_TO_MANY,
        ...
      },
      comment: { // 配置跟評論的關聯關係

      }
    }
  }
}
複製代碼

由於get方法至關因而直接掛在類prototype上的取值函數,是在super()方法執行時就已經存在的了sql

這種構造函數裏的賦值方法是有問題

// 代碼1
module.exports = class extends think.Model {
  constructor(...args){
    super(...args);
    this.relation = {
      comment: think.Model.HAS_MANY,
      cate: think.Model.MANY_TO_MANY
    };
  }
  getList2(){
    return this.setRelation(true).select();
  }
}
複製代碼

代碼1 是在官方文檔示例中,另外一種對model.relation的定義,試圖在繼承了think.Model的用戶自定義model類的構造函數中經過this給relation賦值,從而傳遞到 Relation的實例中,這是作法沒法實現的。bash

ENV

OS Platform:async

win10 64
複製代碼

Node.js Version:ide

v10.13.0
複製代碼

ThinkJS Version:函數

thinkjs@3.2.10
think-model@1.3.1
複製代碼

緣由分析

翻看think-modelmodel.jsrelation.js的代碼能夠發現:ui

// model.js 代碼2
constructor(modelName = '', config = {}) {
    if (helper.isObject(modelName)) {
      [modelName, config] = ['', modelName];
}
assert(helper.isFunction(config.handle), 'config.handle must be a function');
this.config = config;
this.modelName = modelName;
this.options = {};
this[RELATION] = new Relation(this);
}
複製代碼

==在Model類(代碼2)中,屬性this[Symbol('think-model-relation')]的實例化是在代碼1中子類this.relation初始化以前完成的(畢竟要先實行super()),因此this[RELATION] = new Relation(this)時,傳入的this中,並無自定義的relation屬性。==this

// relation.js 代碼3
  constructor(model) {
    this.model = model;
    this.relation = this.model.relation || {};
    this.relationName = true;
  }
複製代碼

==繼續翻看relation.js(代碼3)的代碼發現,若是Relation類的構造函數沒有接收到有效的relation值,則會把this.relation置爲一個空對象,並且因爲Relation實例化是複製給了一個本地Symbol類型變量,後期在外部或者子類中也沒法引用到了,因此初始化以後是沒法改變的。==spa

另外一種可行的寫法 可是沒什麼卵用 不如用get

// 代碼4
class user extends think.Model {
  constructor(...args){
    super(...args);
  }

/*  get relation() {
    return {
      auths: {
        type: think.Model.HAS_MANY,
        model: 'user_auths',
        fKey: 'id_user',
        relation: false
      }
    }
  }*/

  async getUserByAuthTypeAndIdentifier(authType, identifier) {
    const auth_sql = await this.model('user_auths').setRelation(true).where({auth_type: authType, identifier: identifier}).buildSelectSql();
    return this.alias('u').join({
      table: auth_sql,
      join: 'inner',
      as: 'a',
      on: {
        'id': 'id_user',
      }
    }).find();
  }
}

user.prototype.relation = {
  auths: {
    type: think.Model.HAS_MANY,
    model: 'user_auths',
    fKey: 'id_user',
    relation: false
  }
}
module.exports = user
複製代碼

若是想不用get方法實現 我只想到了上述代碼4這種寫法,也就是在原型上擴展一下。prototype

相關文章
相關標籤/搜索