snowangel
snowangel

Reputation: 3462

Push a hash into an array in a loop rails

I am trying to add hashes to an array whilst iterating through an each loop. Here's my controller code: the line I'm struggling with is setting the @royaltiesbychannel variable in the each loop:

def royalty(isbn)  
 sales_hash_by_channel = Sale.find_all_by_isbn_id(@isbn).group_by(&:channel_id)
 sales_hash_by_channel.each do |ch_id, sale_array|
  @royaltiesbychannel = Array.new() 
  value_total_by_channel = sale_array.sum(&:value) 
  quantity_total_by_channel = sale_array.sum(&:quantity)      
   @isbn.rules.each do |rule|
   next unless rule.channel_id == ch_id   
   case quantity_total_by_channel
   when 0..5000  
   @royaltiesbychannel = @royaltiesbychannel << {ch_id => value_total_by_channel * 0.5}
    # (some other case-when statements)             
  end
 end
end

In the console, when I set the ch_id and the value to something new and push the new values into the array:

@royaltiesbychannel = @royaltiesbychannel << {ch_id => value_total_by_channel * 0.5}

I get a nice array of hashes:

[{1=>100000.0}, {2=>3000.0}] 

However, when I do @royaltiesbychannel.inspect in the view, I get just one key-value pair:

[{2=>3000.0}]

For ref:

@royaltiesbychannel.class = Array
@royaltiesbychannel.class = 1
@sales_hash_by_channel.class = Hash
@sales_hash_by_channel.size = 2
@isbn.rules.size = 4

So it looks like the push into the array is overwriting rather than adding. What am I doing wrong? Have I completely missed the point on how loops and .push work? Many thanks in advance.

Upvotes: 0

Views: 4260

Answers (3)

Douglas F Shearer
Douglas F Shearer

Reputation: 26488

Your @royaltiesbychannel initialization is inside the first loop, so every time it starts that loop again it empties the array. Move it outside the loop and you should get the result you want.

def royalty(isbn)
  @royaltiesbychannel = Array.new()
  sales_hash_by_channel = Sale.find_all_by_isbn_id(@isbn).group_by(&:channel_id)
  sales_hash_by_channel.each do |ch_id, sale_array|
    value_total_by_channel = sale_array.sum(&:value) 
    quantity_total_by_channel = sale_array.sum(&:quantity)      
    @isbn.rules.each do |rule|
      next unless rule.channel_id == ch_id   
      case quantity_total_by_channel
      when 0..5000  
        @royaltiesbychannel = @royaltiesbychannel << {ch_id => value_total_by_channel * 0.5}
        # (some other case-when statements)             
      end
    end
  end

Upvotes: 1

madlep
madlep

Reputation: 49666

You're setting @royaltiesbychannel to a new Array object during each iteration over sales_hash_by_channel should you be instead initialising it once outside of that loop instead?

Upvotes: 1

amit_saxena
amit_saxena

Reputation: 7614

You are initializing the array within the loop:
@royaltiesbychannel = Array.new()

It is being re-initialized each time, therefore you get only one result. Move it outside the each loop.

Upvotes: 3

Related Questions