多層的人員關係


#1

請教一下最近在設計多層的User關係遇到困難
如下圖
image

每個User除了最上層外,只會屬於另一個User
A底下有B1與B2
B1與B2底下分別又有C1,C2與C3
我的做法是在user儲存parent id
但是當我想查詢A底下有多少使用者時必須query多次(看有幾層就幾次)
請問有更好的解法嗎?謝謝!


#2

你可以用 awesome_nested_set 這個gem處理

但邏輯應該會是 獨立的一棵成員樹 來表達使用者關係

別直接用User表當中直接使用

然後 樹的每一個節點 都是一個獨立id 或是獨立的email 或是另外用你的方式去做編號

指令的話 會用到的大概是這些 詳細指令可以在google

  # my_cat.root                  root for this node (節點的根)
  # my_cat.level                 the level of this object in the tree (e.g. root = 0) (結構樹中此對象的級別 LV0 開始)
  # my_cat.parent                the node's immediate parent (該節點的直接父項)
  # my_cat.children              array of immediate children (just those in the next level) (數組的節點孩子)
  # my_cat.ancestors             array of all parents, parents' parents, etc, excluding self (所有父母,父母的父母等的數組,不包括自我)
  # my_cat.self_and_ancestors    array of all parents, parents' parents, etc, including self (所有父母,父母的父母等的數組,包括自我)
  # my_cat.siblings              array of brothers and sisters (all at that level), excluding self (同節點LV 夥伴,不包括自我)
  # my_cat.self_and_siblings     array of brothers and sisters (all at that level), including self (同節點LV 夥伴,包括自我)
  # my_cat.descendants           array of all children, children's children, etc., excluding self
  # my_cat.self_and_descendants  array of all children, children's children, etc., including self
  # my_cat.leaves                array of all descendants that have no children (沒有子節點的所有目標 (就是結構樹 該目地的最底層))



  # my_cat.root?                         true if this is a root node  (如果這是根節點,則為true)
  # my_cat.child?                        true if this is a child node (i.e. it has a parent) (如果這是一個子節點(即它有一個父節點),則為true)
  # my_cat.is_ancestor_of?(obj)          true if nested by any obj ()
  # my_cat.is_or_is_ancestor_of?(obj)    true if nested by any obj or self is obj
  # my_cat.is_descendant_of?(obj)        true if self is nested under obj
  # my_cat.is_or_is_descendant_of?(obj)  true if self is nested under obj or self is obj
  # my_cat.leaf?                         true if this is a leaf node (i.e. it has no children) 如果這是一個沒有子節點點(即它沒有孩子 結構樹最低),則為true 

#move_to_child_of  將節點移動的指令

例如 資料表名稱 :user_tree
查詢 a點的下方有誰

@tree = UserTree.root
@tree.children

然後指令後面還可以繼續接weher
查詢 a點的下方有誰 (類型為manage)

@tree = UserTree.root
@tree.children.where(‘type=?’, ‘manage’)


#3

awesome_nested_set 應該是正解,但另外一方面,其實有這種需求我會建議你先把需求列出來,類似為何需要這樣做,想達到怎樣的目的之類的?因為以基本的『使用者』應該不用這樣的關聯才是,且大都有辦法收斂

很多時候很直覺的解法不會是正解的,所以以上,說不定不用 awesome_nested_set 就可以取得快速解,所以麻煩把需求 / spec 或是 user story 寫清楚哩?


#4

@11110
感謝你的教學

@JokerCatz
感謝你的建議,我會再仔細思考是否真的需要這些層級