Ruby — как эффективно извлекать и группировать определенную информацию из объекта?

#ruby-on-rails #ruby #postgresql #object #model

#ruby-on-rails #ruby #postgresql #объект #Модель

Вопрос:

У меня есть объект, содержащий десятки тысяч заказов. Объект выглядит следующим образом:

 [#<Order id: 4304, order_code: 'AB11', manufacturer_id: 24, ...>, 
 #<Order id: 7664, order_code: 'AB13', manufacturer_id: 24, ...>, 
 #<Order id: 4164, order_code: 'AB255', manufacturer_id: 724, ...>, 
 #<Order id: 7671, order_code: 'AX88', manufacturer_id: 855, ...>,
...]  
 

Теперь, что я пытаюсь получить — я хотел бы получить объект, выглядящий так (или что-то подобное):

 [ 
  {manufacturer_id: 24, orders: [{id: 4304, order_code: 'AB11'}, {id: 7664, order_code: 'AB13'}]},
  {manufacturer_id: 724, orders: [{id: 4164, order_code: 'AB255'}]},
  ...
]
 

Какой наиболее эффективный способ извлечь эту информацию из данного Order объекта? Это будет выполняться пару раз в день.

Спасибо.

Ответ №1:

Вы можете сделать что-то вроде этого

 list.group_by(amp;:manufacturer_id).map do |k,v| 
  { 
    manufacturer_id: k, 
    orders: v.collect{ |o| {id: o.id, order_code: o.order_code }}  
  }      
end  
 

вывод выглядит следующим образом

 => [{:manufacturer_id=>24, :orders=>[{:id=>4304, :order_code=>"AB11"}, {:id=>7664, :order_code=>"AB13"}]}, {:manufacturer_id=>724, :orders=>[{:id=>4164, :order_code=>"AB255"}]}, {:manufacturer_id=>855, :orders=>[{:id=>7671, :order_code=>"AX88"}]}]
 

Ответ №2:

В итоге я бы получил какой-нибудь презентатор, что-то вроде PORO (обычный старый объект ruby)

 
class OrderPresenter
  attr_reader :records

  def initialize(records)
    @records = records
  end

  def as_json
    records.group_by(amp;:manufacturer_id).map do |k, v| 
      { 
        manufacturer_id: k, 
        orders: v.collect { |o| {id: o.id, order_code: o.order_code } }  
      }      
    end  
  end
end
 

И я не думаю, что вам нужны все сразу?
Таким образом, вы можете сделать что-то вроде частичной загрузки, чтобы не взорвать всю вашу память

 records.each_slice(1000) do |group|
  data = OrderPresenter.new(records).as_json
  # perform something on that data
end