2016-09-15 4 views
0

Ich bin ziemlich neu in ROR und ich bin in Schwierigkeiten, dies zu erreichen.Wie group_by auf Schienen

Ich habe ein Working_hour Modell und ein Händler-Modell, wo Händler has_many working_hours und working_hour Merchant gehört, wie folgt:

class Merchant < ApplicationRecord 
    has_many :working_hours, inverse_of: :merchant, dependent: :destroy 
    accepts_nested_attributes_for :working_hours, reject_if: :all_blank, allow_destroy: true 
end 

Arbeitsstunde Tabelle

create_table "working_hours", force: :cascade do |t| 
    t.integer "day" 
    t.time  "open_time" 
    t.time  "close_time" 
    t.integer "merchant_id" 
    t.datetime "created_at", null: false 
    t.datetime "updated_at", null: false 
    t.index ["merchant_id"], name: "index_working_hours_on_merchant_id" 
end 

Der Händler zwei working_hours haben kann für den gleichen Tag.

Meine Ansicht:

<% @merchant.working_hours.order(:day).each do |wh| %> 
    <li> 
    <%= t(:"date.abbr_day_names")[wh.day.to_i] %> : 
    <%= wh.open_time.to_formatted_s(:time) %> - 
    <%= wh.close_time.to_formatted_s(:time) %> 
    </li> 
<% end %> 

Wenn ich die Ansicht von Tag abgerufenen Daten geordnet angezeigt werden, sind:

Mon: 10:00-13:00 
Mon: 17:00-20:00 
Tue: 10:00-13:00 
Tue: 17:00-21:00 
Wed: 10:00-13:00 

Wie kann ich Gruppe die working_hours von Tagen und auf diese Weise angezeigt werden:

Mon: 10:00-13:00/17:00-20:00 
Tue: 10:00-13:00/17:00-21:00 
Wed: 10:00-13:00 

Ich sah das group_by Tutorial aus dem Railscast, aber ich habe keinen Controller zu Working_hour Modell. Irgendwelche Ideen?

+0

Sieht aus, als ob Sie alle Daten haben, die Sie aus Ihrer Sicht benötigen. Sie müssen es nur richtig manipulieren. Vielleicht posten Sie den Code aus Ihrer Sicht? – phillyslick

+0

Ich habe meine Frage bearbeitet. Ist es einfach, das Ben zu tun? – user1301037

Antwort

1

Sie könnten Rubin Enumerator des group_by verwenden, die Sie mit der Struktur eine neue Kollektion geben

{ 
    key: matching collection items (minus item grouped on), 
    key2: matching collection items (minus item grouped on) 
} 

Dies bedeutet, Ihre .each wird nun auf eine Hash-Struktur angewendet werden, wo die Schlüssel werden entweder eine ganze Zahl oder die Sache, nach der Sie gruppiert sind, Tag in diesem Fall, bei dem es sich auch um eine Ganzzahl handelt, und eine Untersammlung, die zwar übereinstimmt, aber das Attribut, das Sie gruppiert haben, daraus entfernt hat. Also in Ihrem Fall könnten Sie umschreiben

<% @merchant.working_hours.order(:day).each do |wh| %> 
    <li> 
    <%= t(:"date.abbr_day_names")[wh.day.to_i] %> : 
    <%= wh.open_time.to_formatted_s(:time) %> - 
    <%= wh.close_time.to_formatted_s(:time) %> 
    </li> 
<% end %> 

als

<% @merchant.working_hours.order(:day).group_by(&:day).each do |day, whs| %> 
    <%= t(:"date.abbr_day_names")[day.to_i] %> : 
    <%= whs.each_with_index do |wh, index| %> 
    <li> 
     <%= wh.open_time.to_formatted_s(:time) %> - 
     <%= wh.close_time.to_formatted_s(:time) %> 
    </li> 
    <%# if we have more than one entry add slash %> 
    <%= if index > 0 %> 
    /
    <% end %> 
    <% end %> 
<% end %> 

Beachten Sie, dass dies bedeutet, dass alle die Gruppierung auf der rubin Schicht getan wird, um die Probleme für große Datensätze verursachen wird, und auch du bist jetzt In der Ruby-Ebene verlieren Sie also die AREL-Lazy-Loading-Funktionen, zsort muss jetzt in Ruby ausgeführt werden, anstatt eine neue SQL-Reihenfolge auf die "Untersammlung" anzuwenden. Sie möchten idealerweise eine SQL-Gruppe erstellen, aber das ist für eine andere Zeit.

Hinweis Ich habe diesen Code nicht getestet, damit er explodiert, wie es ist ... YMMV und Sie müssen es ein bisschen neu formatieren, ich bin mir sicher.

+0

Vielen Dank. Für den Moment funktioniert das. =) Empfiehlst du einem Neuling irgendwelche Materialien, um etwas über die SQL-Gruppe zu lernen? – user1301037

+0

Dies ist ein guter Artikel zu starten? https://alexpeattie.com/blog/grouping-activerecord-by-day-o-week-with-datetrunc – user1301037

+0

ja meist nur Google-Fu oder Ihre lokale Bibliothek. SQL hat sich im Kern nicht sehr verändert, daher sollten die meisten Dinge in Ihrer Bibliothek relevant sein. Wenn Sie MySQL verwenden und Geschwindigkeit wünschen, wurde dies empfohlen, als ich anfing, http://shop.oreilly.com/product/0636920022343.do – engineerDave

1

Sie können die Werte in einem Hash speichern und zum Drucken im erforderlichen Format verwenden.

Die Schlüssel in der Hash wird t(:"date.abbr_day_names")[wh.day.to_i] und Werte wird Array von wh.open_time.to_formatted_s(:time) - wh.close_time.to_formatted_s(:time)

@merchant_working_hours = {} 
@merchant.working_hours.order(:day).each do |wh| 
@merchant_working_hours[t(:"date.abbr_day_names")[wh.day.to_i].to_s] ||= [] 
@merchant_working_hours[t(:"date.abbr_day_names")[wh.day.to_i].to_s] = wh.open_time.to_formatted_s(:time).to_s + '-' + wh.close_time.to_formatted_s(:time).to_s 

Ende

Sie können dann @merchant_working_hours hash

benutzen,
<% @merchant_working_hours.each do |key,value| %> 
<%= key: value%> 
<% end %> 

, um die Werte im erforderlichen Format zu drucken, und Sie können die Werte für Erstellt am und Aktualisiert um Werte oder Öffnungszeit und Schließzeit für denselben Tag verwenden oder nicht verwenden, wenn Sie über eine Woche Daten haben.

+0

beachten Sie dies ist im Grunde, was Ruby's Group_by tut – engineerDave