2013-04-24 2 views
0

Каков наилучший способ группировки параметров при использовании MongoDB?Как сгенерировать optgroup в рельсах с Mongoid?

Я использую 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 (one) к Resource (many) не наоборот». Другой способ был бы путаным, поскольку мы будем иметь дело с пользовательскими вложенными массивами без каких-либо отношений, в отличие от объектов ORM.

Поэтому мой желаемый результат может быть сгенерирован следующим кодом Ruby (single-line) в ERB :

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

..where :resources и :name принадлежит ResourceType и :id и :title предназначены для Resource «s вариантов.

Надеюсь, что это поможет и другим.

-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>]] 
    ] 
    
  • last вызов метода в каждой строке массива, возвращаемого на шаге 1 возвращает массив объектов ресурсов.

  • Метод first вызывает в каждой строке массив, возвращенный на шаге 1, возвращает имя типа ресурса.
  • Метод вызова id и name для каждой строки массива, возвращаемого на этапе 2, возвращает идентификатор и имя объекта ресурса.
0

Здесь несколько вещей неправильные.

  1. Вы, кажется, путаете Enumerable#group_by с базой данных GROUP BY оператор.
  2. Как вы думаете, откуда взялось название типа ресурса? Кажется, он не находится в Ресурсе.

Похоже, что имя типа ресурса находится в другой коллекции, и вам придется сопоставлять идентификаторы имен отдельно. Это часть NoSQL для Mongoid: вы не можете просто присоединиться к таблицам Resource и ResourceType.

Resource.all.group_by { |r| r.resource_type_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)) %> 

Надеется, что это помогает! Наслаждайтесь!

Смежные вопросы