2012-07-17 280 views
3

我在尋找什麼必須是一個常見的情形最佳實踐:按摩稀疏記錄從一個Rails(ActiveRecord的,SQL)數據庫表拉到友好爲HTML渲染表的結構。將Rails的ActiveRecord中的稀疏數據轉換爲HTML表格的格式?

出於性能方面的原因,我做它返回的數據是這樣的(我已經簡化爲清晰起見,例子)一個查詢:

Lineitem.all 
=> [#<Lineitem id: 1, username: "Bob", category: "A", amount: 10>, 
    #<Lineitem id: 2, username: "Bob", category: "C", amount: 20>, 
    #<Lineitem id: 3, username: "Jen", category: "A", amount: 30>, 
    #<Lineitem id: 4, username: "Ken", category: "B", amount: 40>, 
    #<Lineitem id: 5, username: "Ken", category: "E", amount: 50>] 

我的目標是一個HTML表格是這樣的:

   A  B  C  D  E 
      --- --- --- --- --- 
    Bob  10   20 
    Jen  30 
    Ken    40    50 
    Sam 

在每個類別被存儲在一個數據庫中的單獨的列這將是微不足道的(或者,如果我使用NoSQL的......?!),或者如果我不關心分貝的性能。

爲了解決它,我一直在寫臭助手代碼是這樣的:在這個

# create hash lookup, index first by username then by category, eg: 
# ["Bob"]["A"] = #<Lineitem id: 1, ...> 
# ["Bob"]["C"] = #<Lineitem id: 2, ...> 
# ["Jen"]["A"] = #<Lineitem id: 3, ...> ... 
def index_lineitems(lineitems) 
    h = {} 
    lineitems.each do |li| 
    h[li.username] = {} unless h.key? li.username 
    h[li.username][li.category] = li 
    end 
    h 
end 

# look up value from indexed hash 
def get_lineitem_amount(indexed_lineitems, username, category) 
    if indexed_lineitems.key?(username) && indexed_lineitems[username].key?(category) 
    indexed_lineitems[username][category].amount 
    else 
    "" 
    end 
end 

或一些變化。然後我確定是什麼行和列的最終名單將是(注意這個「山姆」行......),並通過循環,每次調用get_lineitem_amount渲染HTML表格。這是很糟糕的代碼,我很尷尬地分享它。

當然還有一個更清潔,更面向對象和Rails友好的方式來這個共同的問題。

有什麼建議嗎?

回答

1

我做的非常相似稍微乾淨的東西:

比方說,這是在控制器:

@data = LineItem.all 

這是視圖

columns = @data.map(&:category).uniq 

%table 
    %thead 
    %tr 
     %th &nbsp; 
     - columns.each do |column| 
     %th= column 
    %tbody 
    - @data.group_by(&:username).each do |username, rows| 
     %tr 
     %td= username 
     - cursor = 0 
     - rows.group_by(&:category).sort_by{|cat,rows| columns.index(cat)}.each do |category, rows| 
      - until cursor == columns.index(category) do 
      - cursor += 1 
      %td &nbsp; 
      %td= rows.sum(&:amount) 

它得到一噸清潔如果您將列存儲在單獨的數據庫表中,並且只將它們包含到當前模型中,那麼您可以將索引位置存儲在對象上,而不需要在運行時計算它們,並且對訂單沒有很好的控制。一個額外的查詢並不會打破應用程序的性能。

+0

感謝,這是有益的!我還計劃探索使用一箇中間對象,一個封裝該邏輯清理視圖更多(可能提供一個迭代?)我會後一個後續如果這個平移出來的。乾杯。 – 2012-07-20 21:03:52

相關問題