Создание хэша в Rails 3 - PullRequest
0 голосов
/ 22 мая 2011

У меня есть метод, который рассчитывает роялти для ISBN.Делит продажи по каналам продаж.Ставка роялти определяется общим проданным количеством, а роялти рассчитывается путем умножения ставки роялти (в процентах) на общий доход.Таким образом, результатом должен быть рассчитанный показатель роялти для каждого канала продаж, для каждого isbn.Простите за то, что, вероятно, закомментировал код.

В методе show isbns_controller:

@isbn = Isbn.find(params[:id])

def royalty(isbn)
  @royaltiesbychannel = Hash.new()     
  # Returns all sales for the current isbn, and groups them by channel_id in a hash 
  # {1 => sale 1, sale 2}, {2 => sale 1, sale 2}
  # Then loops through each key-value pair.    
  @isbn.sales.group_by(&:channel_id).each do |ch_id, sale_array|
    # Takes the sales grouped by channel, and totals the quantities and values into two separate variables. 
    value_total_by_channel = sale_array.sum(&:value)  
    quantity_total_by_channel = sale_array.sum(&:quantity)  
     # Gets all the rules for the isbn
     @isbn.rules.each do |rule|
       # Jumps to the next sales hash unless the channel ids match
       next unless rule.channel_id == ch_id
       if Range.new(rule.lower,rule.upper).include?(quantity_total_by_channel)
         @royaltiesbychannel[ch_id] = value_total_by_channel * rule.rate
       end
     end
   end
 end

Это последняя строка, которая вызывает у меня проблему.Я хочу создать хеш с идентификаторами каналов в качестве ключей и рассчитанными роялти в качестве значений.Но вместо этого он создает хеш с одной парой ключ-значение, что-то вроде этого:

{1=>#<BigDecimal:10132a620,'0.875E5',9(36)>}

Я подозреваю, что что-то не так с тем, как я создаю новый хеш в верхней частиметод, а также с попыткой объявить ключ в квадратных скобках.

rule.rate - это процент, выраженный в десятичном виде, например 0,10.Значение является целым числом (на данный момент, по крайней мере).Любые мысли о том, как генерировать этот хэш?

Во-вторых, каков наилучший способ перебора полученного хэша в представлении?

Большое спасибо заранее.

Обновление - вывод .inspect по запросу:

{1=>[#<Sale id: 1, isbn_id: 2, quantity: 3000, value: 122000, currency: "", total_quantity: nil, created_at: "2011-05-16 19:52:36", updated_at: "2011-05-22 14:28:33", customer: "WHS", retail_price: nil, discount: nil, channel_id: 1, invoice_date: "2011-02-01", rule_id: nil>, #<Sale id: 2, isbn_id: 2, quantity: 500, value: 3000, currency: "", total_quantity: nil, created_at: "2011-05-19 09:55:00", updated_at: "2011-05-19 09:55:00", customer: "Borders", retail_price: nil, discount: nil, channel_id: 1, invoice_date: nil, rule_id: nil>], 2=>[#<Sale id: 6, isbn_id: 2, quantity: 10, value: 2000, currency: "", total_quantity: nil, created_at: "2011-05-19 10:34:34", updated_at: "2011-05-19 11:21:07", customer: "Bookshop a", retail_price: nil, discount: nil, channel_id: 2, invoice_date: nil, rule_id: nil>, #<Sale id: 7, isbn_id: 2, quantity: 2000, value: 4000, currency: "", total_quantity: nil, created_at: "2011-05-19 10:34:49", updated_at: "2011-05-19 10:34:49", customer: "Bookshop b", retail_price: nil, discount: nil, channel_id: 2, invoice_date: nil, rule_id: nil>]}

Второе обновление: изменение вопроса:

Спасибо за ваши мысли.Оказывается, что метод работает нормально, потому что хэш, сгенерированный @isbn.sales.group_by(&:channel_id), содержит только одну пару ключ-значение.Таким образом, мой вопрос остается в силе, но для другого фрагмента моего кода: как выполнить поиск по модели Sales для получения массива хэшей, например {1 => sale 1, sale 2}, {2 => sale 1, sale 2}?

Я пробовал эту ужасную вещь:

@channelarray = Channel.select(:id).all  
@salesbychannelwrong = @channelarray.group_by {|i| Sale.where("channel_id = ?",i).where("isbn_id =?", @isbn)}   
@salesbychannel = @salesbychannelwrong.invert

, которая дает это:

{[#<Channel id: 1>]=>[#<Sale id: 1, isbn_id: 2, quantity: 3000, value: 122000, currency: "", total_quantity: nil, created_at: "2011-05-16 19:52:36", updated_at: "2011-05-22 14:28:33", customer: "WHS", retail_price: nil, discount: nil, channel_id: 1, invoice_date: "2011-02-01", rule_id: nil>, #<Sale id: 2, isbn_id: 2, quantity: 500, value: 3000, currency: "", total_quantity: nil, created_at: "2011-05-19 09:55:00", updated_at: "2011-05-19 09:55:00", customer: "Borders", retail_price: nil, discount: nil, channel_id: 1, invoice_date: nil, rule_id: nil>], [#<Channel id: 2>]=>[#<Sale id: 6, isbn_id: 2, quantity: 10, value: 2000, currency: "", total_quantity: nil, created_at: "2011-05-19 10:34:34", updated_at: "2011-05-19 11:21:07", customer: "Bookshop a", retail_price: nil, discount: nil, channel_id: 2, invoice_date: nil, rule_id: nil>, #<Sale id: 7, isbn_id: 2, quantity: 2000, value: 4000, currency: "", total_quantity: nil, created_at: "2011-05-19 10:34:49", updated_at: "2011-05-19 10:34:49", customer: "Bookshop b", retail_price: nil, discount: nil, channel_id: 2, invoice_date: nil, rule_id: nil>]}

Я также пытался

Sale.find_by_isbn_id(:id).group_by(&:channel_id)

, который возвращаетnil

и это

Sale.find_by_isbn_id(@isbn).group_by(&:channel_id)

, которое возвращает

undefined method `group_by' for #<Sale:0x0000010122df60>

У меня есть следующие модели:

class Sale
  belongs_to :isbn
  belongs_to :channel
  ...
end

class Isbn
  has_many :rules
  has_many :sales
  has_many :channels, :through => :sales
  ...
end

class Channel
  has_many :sales
  has_many :rules
  ...
end

class Rule
  belongs_to :isbn
  belongs_to :channel
  has_many :sales, :through => :isbn
  ...
end

Еще раз спасибо.

1 Ответ

0 голосов
/ 23 мая 2011

Sale.find_by_isbn_id(@isbn).group_by(&:channel_id) => Sale.find_all_by_isbn_id(@isbn).group_by(&:channel_id)

или

Sale.where(:ibn_id => @isbn.id).group_by(&:channel_id)
...