2016-07-08 5 views
0

Da Veranstaltungsort ein Feld „featured_level“ hat, der von 0 bis N.Sortieren nach Attribute und randomisieren rezidivierende

Ich muß zurückkehren Veranstaltungsorte geordnet nach featured_level, aber Randomisierung der Reihenfolge der Orte mit dem gleichen gehen könnte featured_level.

UPDATE:

Mit der gegebenen Antwort Ich habe diese Methode:

def self.by_featured_level 
    all.group_by {|v| v.featured_level}.inject([]) { |memo, (level,values)| 
    memo << { level => values.shuffle } 
    }.map { |hash| hash.values }.flatten.reverse 
end 

Aber es scheitert den folgenden Test (auch mit reellen Zahlen nicht richtig funktioniert), ich versuche immer noch zu es herausfinden, Test verwendet:

describe "by featured level" do 
    before do 

    @venue1 = create(:venue, featured_level: 5) 
    @venue2 = create(:venue, featured_level: 2) 
    @venue3 = create(:venue, featured_level: 4) 
    @venue4 = create(:venue, featured_level: 2) 
    @venue5 = create(:venue, featured_level: 0) 
    @venue6 = create(:venue, featured_level: 2) 
    @venues = Venue.by_featured_level 

    end 

    it { 
    start_with_hightest = @venues.index(@venue1) == 0 
    expect(start_with_hightest).to be_truthy 
    } 
    it { 
    second_hightest_is_2nd = @venues.index(@venue3) == 1 
    expect(second_hightest_is_2nd).to be_truthy 
    } 
    it { 
    ends_with_lowest = @venues.last.id == @venue5.id 
    expect(ends_with_lowest).to be_truthy 
    } 
end 

Antwort

0

ich brauchte ursprünglich einen Activerecord :: Relation statt einem Array (das @ Rückkehr von zezetic Antwort ist, so dass am Ende tat ich:

scope :by_featured_level, -> { 
     select("venues.*, (random() * 9 + 1) AS rdn").order('featured_level DESC, rdn') } 
1

Start Lassen sie uns von den Veranstaltungsorten zu sammeln:

require 'ostruct' 

@venue1 = OpenStruct.new(id: :a, level: 0) 
@venue2 = OpenStruct.new(id: :b, level: 2) 
@venue3 = OpenStruct.new(id: :c, level: 2) 
@venue4 = OpenStruct.new(id: :d, level: 2) 
@venue5 = OpenStruct.new(id: :e, level: 4) 
@venue6 = OpenStruct.new(id: :f, level: 5) 

@venues = [@venue1, @venue2, @venue3, @venue4, @venue5, @venue6] 

Wir wollen pro Level randomisieren, so dass wir Gruppen erstellen:

@venues.group_by { |v| v.level } 

Dies gibt einen Hash, wo die Orte von jeder Ebene indiziert sind.

nun über den Hash iterieren und einen neuen Hash zurück, wo die Werte randomisiert wurden:

@venues. 
    group_by {|v| v.level}. 
    inject([]) { |memo, (level,values)| 
    memo << { level => values.shuffle } 
    } 

Dieser Hash nun abgeflacht werden kann, so dass das Endergebnis eine Liste von Hashes ist, pro Ebene randomisiert:

@venues. 
    group_by {|v| v.level}. 
    inject([]) { |memo, (level,values)| 
    memo << { level => values.shuffle } 
    }. 
    map { |hash| hash.values }. 
    flatten 
+0

ich diesen Fehler: Typeerror: keine implizite Umwandlung von Symbol in Integer Voll Test: http://pastebin.com/XgW3RnjM – fabriciofreitag

+0

Ja, einige Fehler gemacht. Probieren Sie die überarbeitete Version. – zetetic

+0

Funktioniert immer noch nicht richtig, ich aktualisierte den Code mit der Implementierung und Test. – fabriciofreitag