2011-02-11 24 views
7

Kullanıcı için temizlemek istediğim geniş bir veri kümem var. Ben çıkış olarak yukarıda çok aynı sırada benim bakışın da yukarıdaki, sorun çok tekrarlanan olduğunda Şu andaRuby/Rails - Bir Dizideki Sorgu Sonuçlarını Nasıl Birleştirme?

ID | project_id | thread_id | action_type |description 
1 | 10   | 30  | comment | yada yada yada yada yada 
1 | 10   | 30  | comment | xxx 
1 | 10   | 30  | comment | yada 313133 
1 | 10   | 33  | comment | fdsdfsdfsdfsdfs 
1 | 10   | 33  | comment | yada yada yada yada yada 
1 | 10   |   | attachment | fddgaasddsadasdsadsa 
1 | 10   |   | attachment | xcvcvxcvxcvxxcvcvxxcv 

: DB'den veri seti şuna benzer.

Ben Ruby nasıl yapılacağını öğrenmek istiyorum Ne, birkaç nasıl bir projesindeki ve thread_id altında bir dizi ve aggreate açıklamaları oluşturmak olduğunu
10 - 30 - yada yada yada yada yada 
10 - 30 - xxxxx 
10 - 30 - yada yada yada yada yada 

, bunun yerine çıkış: Örneğin, projesindeki 10 & 30 thread_id Gördüğünüz geçerli:

10 - 30 
- yada yada yada yada yada 
- xxxxx 
- yada yada yada yada yada 

üzerinde herhangi bir tavsiye

başlamak için? Bu gereksinim benim için yeni, bu yüzden bunu çözmek için en iyi yolu düşündüğünüze dair düşüncelerinizi takdir ediyorum. Etkinlik feed'inin etkinlik türlerinde büyük olasılıkla büyümeye devam etmesi nedeniyle, bu, Ruby'de değil, Ruby'de yapılabilir. karmaşıklık.

Teşekkür Ruby

+0

SQL yaklaşımı için GROUP BY kullanın. Ruby yaklaşımı için Enumerable # group_by kullanın. Dokümanları kontrol et. – tokland

+1

Bu veriler hangi formda çalışıyor? ActiveRecord nesneleri veya JSON nesneleri mi yoksa başka bir şey mi? –

+0

@Pan, bu veri bir ActiveRecord nesnesidir, örneğin @aktivite – AnApprentice

cevap

10

kullanın group_byhttp://apidock.com/rails/Enumerable/group_by veya sağ SQL. Ruby: Sonra

sets = DataSet.all.group_by{ |data| [data.project_id, "-", data.thread_id].join(" ") } 

böyle Hash alırsınız:

<% sets.each do |range, datas| %> 
    <p><%= range %>:</p> 
    <% datas.each do |data| %> 
    <p><%= data.description %></p> 
    <% end %> 
<% end %> 

UPD each_with_index

<% sets.each_with_index do |datas, index| %> 
    <p><%= datas[0] %>:</p> 
    <% datas[1].each do |data| %> 
    <p><%= data.description %></p> 
    # some stuff with *last* 
    <%= "This is the last one" if data == datas[1].last %> 
    <% end %> 
<% end %> 
için: Eğer görünümünde ayrıştırabilir

{ "10 - 30" => [#DataSet1, #DataSet2 ...], "10 - 33" => [#DataSet7, #DataSet11 ...] 

+0

Bu, rayların henüz yapılmadığını gördüğüm en etkileyici şey olmalı. – AnApprentice

+0

Bir endekse ihtiyacım vardı, bu yüzden onu <% sets.each_with_index ...... olarak değiştirdim. Sorun bir döngüde olmalı ve her_with_index kullandığımda kırılıyor. Fikirler? – AnApprentice

+0

Cevabı güncelledik – fl00r

0

Enumerator'un group_by yöntemini kullanmak için basit bir yönergeyi takip ediyorum. - Çalıştırılan veri seti küçük ve sabit olmalı ve zamanla sabit kalması sağlanmalıdır.

Örn: Bence etkinlik besleme tablo zamanla hızla büyüyebilir ise

Fixed data-set: Zip codes, city names  
Dynamic but small data-set: User's hobbies  
Dynamic but paginated data-set: First page of latest orders. 

. Activity.all, tüm etkinlikleri belleğe yükler. Bu çağrıyı yürüterek aşırı bellek ve ağ maliyetlerine maruz kalıyorsunuz. all çağrısını koşulsuz koşullarla ve sayfalama ile yürütmek asla iyi bir fikir değildir. Şu anda sonuç kümesini oluşturuyorsanız, sonuç kümesi birden çok sayfayı kapsadığında mevcut çözüm çalışmaz. Doğru sonuç elde etmek için order maddesini kullanmanız gerekir.

Kumandanızda olarak:

Bu ne yapardım olduğunu Şimdi

# order by ensures that ordering happens at the DB 
# pagination and conditions ensures that data set is small 
activities = Activity.paginate(:order => "project_id, thread_id", :page => #pn) 
@activity_groups = activities.group_by{|a| "#{a.project_id} - #{a.thread_id}"} 

, fl00r önerdiği gibi size görünümünde @activity_groups kullanabilirsiniz.

İlgili konular