acts_as_nested_set 與 STI


#1

修改一下內容 感覺我自己都不是很理解說法

參考這個影片

因為繼承的關係

所以 只要在下sql時 帶入 type 並符合結構

就可以連動 STI 架構

例如圖片檔資料夾 文字檔資料夾 利用繼承的概念

但是這算是屬於大類

但是動態file tree 是該如何使用

一個單點控管的狀態

我的概念上應該有4個必備因素

1.acts_as_nested_set樹狀結構
2.單表對應權限 並掛在 acts_as_nested_set 外鍵key即可
3.資料夾的樹
4.資料夾中的檔案

以圖來說
一個資料夾的樹狀結構

slacks(4:5) 資料夾
裡面有n個檔案
對應 acts_as_nested_set 當中的 id 識別當下這個使用者是否在ˇ這個權限樹當中 如果有 再進一步到全縣表找相對應的權限

但是這個是用STI做出來的嗎?

我的感覺是 資料夾結構 本身也是一個 acts_as_nested_set

所以 打開一個連結時會對應
tree1 資料夾的tree
tree2 權限的tree


我的疑問是

以圖的資料夾tree 是用 acts_as_nested_set 配合 STI?

還是 單獨一個表 在掛上 acts_as_nested_set 當作資料夾tree運作

還是說 有工具可以直接 send_date 或是send_file 的方式 把資料夾讀出來就好

還會顧慮說 使用者會一職將樹狀結構動態變大 所以也不可能指定使用者衣錠就是用哪一層

所以 STI 繼承 不知道該如何理解他的動態方式


另外一種做法 感覺也行 但還沒實際去做

2個 acts_as_nested_set 獨立樹

資料夾樹
權限樹

一顆 acts_as_nested_set tree 就一直顯示在畫面 左邊 (資料夾樹)

然後利用ajax的方式 當使用者點選其中一個資料夾樹的node 便到後端驗證 權限樹

驗證完 將結果顯示在右邊

true 返回檔案的link and image

flase 返回空白

這樣就有點檔案總管的fu


#2

我說…你每次都把問題複雜化了,本來的思維其實都超精簡的,其實你『動手做一次然後去看原始資料,就知道該如何跑了』

會說要用 acts_as_nested_set 單純是它多了 L & R 值可以增加效能罷了(類似取得此資料夾下不分層的所有檔案與資料夾),然而如果是單純的 tree 結構其實只需要一個 parent_id 即可,和 Java 的物件與繼承結構一樣,每個人只需要知道老爸是誰即可

[[folders]]
id , parent_id
 1 , null          1 - 3 - (5 & 6)
 2 , null          2 - 4
 3 , 1             7
 4 , 2
 5 , 3
 6 , 3
 7 , null

所以如果我要取得 id3 的下面有哪些資料夾我只需要這樣做即可

SELECT * FROM folders WHERE parent_id = 3

不過『你會需要只有資料夾的檔案系統嗎?你的檔案去哪裡了!?』

依照 Rails 的傳統要建另外一個表,然後標記 folder_id = 3 才行,然後你就要有兩個 SELECT

SELECT * FROM folders WHERE parent_id = 3
SELECT * FROM files WHERE folder_id = 3

如果你在 3 資料夾內有 20 個子資料夾,然後有 123 個檔案,請問分頁系統該如何製作?答案是你要先取得『有多少資料夾在該資料夾內』然後才能對檔案做 OFFSET,如果你要顯示每頁 30 筆檔案與資料夾的話,這樣不是很蠢咪?一件事情要兩個 SQL 且分別處理,還會有 race condition,所以你不如把檔案或資料夾打成同一個表

[[folder_and_files]]
id , type   , parent_id , name
 1 , folder , null      , im_root_folder
 2 , folder , null      , im_root_folder_too
 3 , file   , 1         , testme.jpg
 4 , file   , 2         , TODO.txt
 5 , folder , 1         , im_sub
 6 , file   , 5         , yooo.mpg
 7 , file   , 5         , momo.doc
 8 , folder , 5         , third_me
 9 , folder , 5         , QwQ

依照上面的 DEMO,我只需要一個 SQL 指令還可以馬上做好分類,類似

SELECT * FROM folder_and_files WHERE parent_id = 5 ORDER BY type LIMIT 20

結束,檔案和資料夾混雜結構全有了,每頁 20 筆不多不少,但 folder & file 明明就是兩種東西,一個是概念性只有名字的節點,另外一個有實體檔案的資料,所以 STI 就在做這個,拿 type 分成兩個不同的 model …

class FolderAndFile < ActiveRecord::Base ; end
class Folder < FolderAndFile ; end
class File < FolderAndFile ; end #這命稱是保留字,這邊單純 demo 用的

FolderAndFile.where('parent_id = 5').order('type') #=> [<Folder> , <Folder> , <File> , <File>]
#禁止使用 FolderAndFile 來做 create , 要用 Folder or File 來做 create 即可,會自動寫入 type 欄位

之後再去 each 不就很順了? anyway 概念其實很簡單很好懂,不要複雜化 … 你要做啥資料先展開想清楚,Rails 是啥鬼先丟掉,以 schema 為主,不然 … 你在做啥?

再來,任何一個物件或資料都是多重形態的,可以是 tree 的節點,同時 hash_meny 很多東西,且 belongs 別人,本身可以存檔案,還可以當使用者用,這是可以『同時存在的』,類似你要拿 User 表打組織架構圖,有上司下屬關係,且還可以上傳 Avatar,同時有多個資產,但卻隸屬於某個組織上,我剛講的這個需求就是最前面的所有綜合體,不是嗎?

而你的權限控管…不就是這個複雜的關聯網路內,小小的一個分支出去的關聯罷了,但在這之前你的本身的關聯要先穩定才行,不管如何,學我上面,把資料先展開,schema 先丟出來,看資料流怎樣流動,然後才來管關聯,看是否資料會重複,不然你只會被 Rails 操控,而非操控 Rails 唄?


#3

真的

我在考量的時候 後面好多東西一直思考

最後都卡住@@ 畢竟一環扣一環 看似複雜其實 都就是一個簡單的問題

因為STI的特性 讓我一直疑惑他在這當中所扮演的腳色

檔案的路徑也是我一直卡住思考不出來的項目

經JC講 確實利用STI 解決了我幾個關鍵的問題點

而且問題我還不會自己形容 真的很糟糕…@@

我原本還想問一下 樹結構 有沒有比較方便的"移動"指令

https://nanapi.com/ja/129861

終於有看到比較正常的使用方法 移動

不過部分指令只是方便使用 操控樹 還是一般語法比較快

樹結構 我第一份工作的時候就玩ERP就很熟了

所以在個別專案下我確實還是有其他考量(這個就很煩了 使用者與管理者的堅持與妥協)

但那時候沒有現在這些觀念 前輩都是硬幹 所有的判斷邏輯都是自己弄 部過那時是用C語言就是了 也沒有學過STI這些東西

但是有好工具 也有更好的工具思維 實作工具 也是學習工具

最近一直問這些問題 真的很謝謝JC大的講解