2017-05-16 77 views
1

我有一個相當複雜的關係與多態直通模型。在應用中,有一個標籤系統,用戶和另一個模型可以被標記。爲了避免重複的字符串條目,我使用了一個包含標記ID,標記的模型名稱和標記的實例ID的直通模型(TagLink)。避免重複多態hasAndBelongsToMany通過模型關係

所以我

User --+ 
     | 
     +---> TagLink -----------> Tag 
     |  - tagId    - id 
Item --+  - taggableId   - text 
       - taggableName 
       (User or Item) 

的鏈接關係是hasAndBelongsToMany。問題是,當我發佈一個新標籤到/items/:id/tags/users/:id/tags時,它被保存,但我可以創建儘可能多的相同的文本沒有任何錯誤。

我想什麼,在張貼到/items/:id/tags/users/:id/tags,它:

  • 創建一個新的標籤條目,如果沒有已經存在,然後添加一個新的TagLink條目(這是當前的行爲,但即使在同一個標​​籤已經存在)
  • 單獨創建一個TagLink條目時標籤已經存在

我想到了兩個解決方案:

  • 以某種方式覆蓋Tag的創建方法來檢查是否存在,然後手動創建TagLink條目(如果存在)。如果不是,則默認繼續。
  • 使用〜全部CRUD URI公開標籤列表(/tags),然後強制使用/{items,users}/:id/tags上的標籤ID。

理想情況下,我更喜歡第一個,因爲它更透明,使API更平滑。

所以,任何線索都會受到歡迎!

回答

1

我最終做了第一個解決方案,這很容易。這個想法是在引導腳本中替換User.create方法,該引導腳本找到具有相同text的標籤,並在找到該標籤時將其返回。

module.exports = function(app) { 
    var Tag = app.models.Tag; 

    // Override Tag.create to avoid duplicates 
    Tag.createRaw = Tag.create; 
    Tag.create = function(data, token, cb) { 
     // Find matching tag 
     Tag.findOne({where: {text: data.text}}, (err, tag) => { 
      if (err)  cb(err); 
      // If the tag is found, return it 
      else if (tag) cb(null, tag); 
      // Else create it 
      else   Tag.createRaw(data, token, cb); 
     }); 
    } 
}