2013-04-24 20 views
0

使用MongoDB時將選項分組的最佳方式是什麼?如何使用Mongoid在rails中生成optgroup?

我使用Mongoid,當我嘗試這個辦法:

<%= field.select :resource_id, 
    grouped_options_for_select(Resource.all.group_by{"resource_type_id"}.map {|k,m| 
    [m.first.title, m.first.id] }),:prompt => true %> 

它給了我下面的錯誤:

undefined method `map' for "5177e6a5359f105f89000001":Moped::BSON::ObjectId

雖然我要找:

<select> 
    <optgroup label="RT1"> <!-- RT1 is the name of resource type --> 
     <option value="5177e6a5359f105f89000001">Res1</option> 
    </optgroup> 
</select> 

而且,在控制檯中,Resource.all.group_by{"resource_type_id"}的輸出是

=> {"resource_type"=>[#<Resource _id: 5177e6a5359f105f89000001, 
created_at: 2013-04-24 14:05:25 UTC, updated_at: 2013-04-24 14:54:14 UTC, 
title: {"en"=>"Res1"}, slug: {"en"=>"res1"}, content: 
{"en"=>"This is the content for First Resource."}, 
excerpt: {"en"=>"This is the content for First Resource."}, published: true, 
resource_type_id: "5177e3ba359f10d345000004">]} 

而預期結果是

=> {"RT1"=>[#<Resource _id: 5177e6a5359f105f89000001, 
created_at: 2013-04-24 14:05:25 UTC, updated_at: 2013-04-24 14:54:14 UTC, 
title: {"en"=>"Res1"}, slug: {"en"=>"res1"}, content: 
{"en"=>"This is the content for First Resource."}, 
excerpt: {"en"=>"This is the content for First Resource."}, published: true, 
resource_type_id: "5177e3ba359f10d345000004">]} 

回答

0

Old Pro提到的方法很棒,但比預期的稍長。我花了一些時間在grouped_collection_select helper docs中給出的例子,其要點是:「爲了保持簡單和麪向對象的方式,您必須從ResourceType(一)到Resource(許多)而不是相反」。另一種方式會令人困惑,因爲我們將處理與ORM對象無關的自定義嵌套數組。

因此,我希望的輸出可以由ERB中的以下Ruby(單行)代碼生成:

<%= field.grouped_collection_select :resource_id, ResourceType.order_by([:name,:asc]), 
    :resources, :name, :id, :title, :prompt => true %> 

..where :resources:name屬於資源型和:id:titleResource的選項。

希望它能幫助別人。

-1

我假設你想按resource_type而不是resource_type_id的選項。

f.grouped_collection_select :resource_id, 
          Resource.all.group_by(:resource_type).to_a, 
          :last, :first, :id, :name 

說明

  • Resource.all.group_by(:resource_type).to_a返回數組的數組。

    [ 
        [ "R1", [<Resource _id 51xx0001>, <Resource _id 51xx0002>]], 
        [ "R2", [<Resource _id 51xx0003>, <Resource _id 51xx0004>]] 
    ] 
    
  • 在每一行上的陣列中的步驟中返回1返回資源對象的數組的last方法調用。

  • first方法在每一行調用在步驟1中返回的數組返回資源類型名稱。
  • idname方法調用在步驟2中返回的數組的每一行返回資源對象的id和名稱。
0

這裏有幾件事情是錯誤的。

  1. 您似乎已將Enumerable#group_by與數據庫GROUP BY運算符混淆。
  2. 您認爲資源類型的名稱來自哪裏?它似乎不在Resource中。

它看起來像資源類型的名稱是在不同的集合中,你將不得不分別映射到名稱的名稱。這是Mongoid的NoSQL部分:你不能簡單地加入Resource和ResourceType表。

Resource.all.group_by { |r| r.resource_type_id } 

會讓你開始,但散列鍵將是ID,而不是名稱。 (這也會將所有資源一次讀入內存,這在很多情況下都會成爲問題,但由於您將它們全部顯示在選項列表中,因此我認爲列表足夠小以至於可以。)然後需要獲得一個名稱映射並替換散列鍵。例如:

resource_names = {} 
ResourceType.each { |rt| resource_names[rt.id] = rt.name } 
resource_groups = Resource.all.group_by { |r| r.resource_type_id } 
resource_options = Hash[resource_groups.map { |k, v| [resource_names[k] || k, [v.title["en"], v.id]] }] 
0

這裏的OPTGROUP的例子:

@city_group = 
       [ 
       ["Wisoncin", [["Lake Geneva", "1"], 
       ["Elkhart Lake", "2"]]], 
       ["Michigan", [["Harbor Country", "3"], ["Traverse City", "4"]]], 
       ["Indiana", [["Bloomington", "5"], ["Valparaiso", "6"]]], 
       ["Minnesota", [["Twin Cities", 
       "7"], ["Bloomington", "8"], ["Stillwater", 
       "9"]]], 
       ["Florida", [["Sanibel & Captiva", "10"]]], 
       ["Illinois", [["Chicago", "11"], 
       ["Galena", "12"]]], 
       ] 

,並在您的觀點補充一點:

<%= select_tag(:brand_id, grouped_options_for_select(@city_group, selected_key = "11", prompt = nil)) %> 

希望它能幫助!請享用!