2016-09-15 28 views
0

我是ROR的新手,我很難做到這一點。Rails上的group_by怎麼樣

我有一個Working_hour型號和商人模型,其中商人的has_many working_hours和working_hour屬於商人,如下:

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 

工時表

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 

商家可以有兩個working_hours同一天。

我的觀點:

<% @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 %> 

當我在一天下令檢索到的數據的視圖中顯示爲:

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 

我怎麼能集團通過天working_hours和顯示是這樣的:

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

我看了Railscast的group_by教程,但我沒有一個控制器working_hour模型。有任何想法嗎?

+0

看起來你已經掌握了你所需要的所有數據。你只需要正確操縱它。也許從你的視角發佈代碼? – phillyslick

+0

我編輯了我的問題。做這個Ben很簡單嗎? – user1301037

回答

1

你可以使用紅寶石枚舉的group_by這將給你與結構的新的集合

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

這將意味着你的。每個現在將被應用到一個Hash結構,其中鍵將成爲一個整數或者你分組的東西,在這種情況下,也恰好是一個整數,以及一個子集合,但它具有從groupped中刪除的屬性。所以你的情況,你可以重寫

<% @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 %> 

<% @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 %> 

注意,這意味着所有的分組被紅寶石層,這將導致對大型數據集的問題上進行的,並且還你現在在紅寶石層,所以你失去了AREL延遲加載功能,例如現在需要用ruby來進行排序,而將新的SQL順序應用於「子集合」。你理想上想要做一個SQL組,但那是另一回事。

注意我沒有測試這個代碼,所以它可能會炸燬,因爲... YMMV,你必須重新格式化它,我敢肯定。

+0

謝謝。現在這個工作。 =) 您是否推薦任何材料供新手學習有關SQL組? – user1301037

+0

這是一篇很好的文章? https://alexpeattie.com/blog/grouping-activerecord-by-day-or-week-with-datetrunc – user1301037

+0

耶大部分只是谷歌福或你的本地圖書館。 SQL在覈心方面沒有太多改變,所以你圖書館的大部分內容都應該是相關的。如果你使用MySQL並且想要速度,那麼當我開始時,這是推薦的,http://shop.oreilly.com/product/0636920022343.do – engineerDave

1

您可以將值保存在散列中,並以所需格式打印。

中的散列將t(:"date.abbr_day_names")[wh.day.to_i]陣列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 

然後可以使用@merchant_working_hours散列

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

以所需格式打印值,並且您可以使用創建值和更新值或開放時間和關閉時間來檢查同一天,如果您的數據超過一週。

+0

注意這基本上是ruby的group_by的什麼 – engineerDave