Topic: Block object not iterating?

The following block of code is being used to populate data into my rails application db:

  def make_group_members
    User.all.each do |user|
      Group.all.each do |group|
        Membership.create do |membership|
          membership.member_id = user.id,
          membership.group_id = group.id,
          membership.status = "pending"
        end
      end
    end   
  end

I have 10 users and 10 groups.  When the file executes, as expected, the table is populated with 100 records.  The group_id column has 10 records for each of the 10 groups.

The problem is that the member_id column is populated with the value "1".  However, I'm expecting the member_id column to be "1" for the first 10 records, "2" for the next 10 records and so on...

foolishly, I've killed almost 4 hours trying to troubleshoot this today.

Thanks for your help!!!

Re: Block object not iterating?

It's normal. Let's start from the very low level,  - looping on every group (from 1 to 10): in this case the user will be always the same, user_id = 1 for example. You will get the first 10 records for user.id = 1:

member_id | group_id |  status
 1                | 1             | 'pending
 1                | 2             | 'pending
 1                | 3             | 'pending
 1                | 4             | 'pending
 1                | 5             | 'pending
 1                | 6             | 'pending
 1                | 7             | 'pending
 1                | 8             | 'pending
 1                | 9             | 'pending
 1                | 10           | 'pending

The first iteration on user with id=1 is finished and the second one will start. You will get the same but the member_id will be set to the next user.id = 2:

member_id | group_id |  status
 2                | 1             | 'pending
 2                | 2             | 'pending
 2                | 3             | 'pending
 2                | 4             | 'pending
 2                | 5             | 'pending
 2                | 6             | 'pending
 2                | 7             | 'pending
 2                | 8             | 'pending
 2                | 9             | 'pending
 2                | 10           | 'pending

And so on till the last user.id = 10.

Last edited by Javix (2011-06-09 03:55:31)

Re: Block object not iterating?

Thanks Javix.  I would be happy if the block executed as your post mentions (that's the intent.)  The problem is that the entire db table user_id column is populated with the user_id of "1" (for all 100 records!)

That's what I can't figure out.

The block outputs 100 records as expected.  The first 10 belong to the first user and it cycles through the 10 groups.  the problem is that the 2nd, 3rd...10th batch also all belong to the first user!

At least your post confirms that my logic is not skewed.

Thanks again!!

Re: Block object not iterating?

Oh, one more update...  If I reverse the order of the .each loop (move the Group.all.each line ahead of the User.all.each line) the problem is reversed (i.e., the 100 row group_id column is all populated with group_id = "1".

I've tried throwing the 2nd portion of the block (beginning with the 2nd loop) into a lambda but that didn't help.

Re: Block object not iterating?

SOLVED - Just in case this helps anyone else out...

Here's the code that works as expected.  For some reason I had to pass the id as a parameter of the .create statement and then execute the block.  I still don't know why the original way didn't work properly.  For some reason Ruby didn't want to give up the first id from memory.

  def make_group_members
    Group.all.each do |group|
      User.all.each do |user|
        user.memberships.create(:group_id => group.id) do |membership|
          membership.status = "pending"
        end
      end
    end   
  end