Rails(ActiveRecord、SQL)dbテーブルから引き出されたスパースレコードを、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
各カテゴリが db に個別の列として格納されている場合 (または NoSQL を使用していた場合...?!)、または db のパフォーマンスを気にしない場合、これは些細なことです。
それを解決するために、私は次のような臭いヘルパー コードを書き続けています。
# 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
またはこれに関するいくつかのバリエーション。次に、行と列の最終的なリストを決定し ("Sam" 行に注意してください...)、get_lineitem_amount
毎回ループして呼び出して HTML テーブルをレンダリングします。これは非常に悪いコードなので、共有するのが恥ずかしいです。
確かに、この一般的な問題に対する、よりクリーンでオブジェクト指向と Rails に適したアプローチがあります。
何かアドバイス?