0

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.

8
  • 2
    for one thing, you should put all that logic in your models :) Commented May 25, 2011 at 11:28
  • 1
    So true. I wondered about getting the thing to work first then refactoring... Commented May 25, 2011 at 11:30
  • @royaltiesbychannel = @royaltiesbychannel << {ch_id => value_total_by_channel * 0.5} why are you equating royaltiesbychannel to itself? you can do without the = sign, and thats probably where you're overwriting Commented May 25, 2011 at 11:32
  • and maybe you could refactor first and fix the bug in the process :) refactoring it into a cleaner more understandable code can clear things up for you, showing you why it wasnt working in the first place :) Commented May 25, 2011 at 11:32
  • also, you have an isbn argument on your method, which you are not using? Commented May 25, 2011 at 11:33

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

1

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?

1 Comment

hey @madlep, could you edit this answer, I accidently click down vote and it is locked now. going to revert it once you edit the answer plz. thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.