Kaleem Ullah
Kaleem Ullah

Reputation: 7049

Strange output | rails each do loop over active records

in Rails 5, I am querying via active records relation and pushing each record in array by each-do looping.

stats_array = []
pUser = {}

userProject = UserProject.find_by(project_id: params[:projectId], user_id: params[:userId])
if userProject && userProject.project.present?
  projectUsers = userProject.project.users.where(role_id: 1..3).page(params[:page]).per(5) 
  projectUsers && projectUsers.each do |pu|
    pUser[:full_name] = pu.full_name
    pUser[:avatar_url] = pu.avatar.url(:medium)
    pUser[:given] = UserTask.where(to_user: pu.id).joins(:task).count
    pUser[:late] = UserTask.where(to_user: pu.id).joins(:task).where(:tasks => {end_date: Date.today.beginning_of_day..Date.today.end_of_day}).count
    pUser[:wip] = UserTask.where(to_user: pu.id).joins(:task).where(:tasks => {state: @@task_wip_code}).count
    puts "=============================="
    puts pUser # outputs correct details
    puts "=============================="
    stats_array.push(pUser)
  end
end

puts "=============================="
puts stats_array # output wrong details
puts "=============================="

in loop when I print user object pUser. it prints correctly. for each different user.

but the problem is when I print stats_array, it prints all the results for single user which ever came last. the array length is correct but results are not.

Out Put in Each-Do loop

======== index 0 =======

{:full_name=>"Super User", :avatar_url=>"missing.png", :given=>14, :late=>0, :wip=>4}

======== index 1 =======

{:full_name=>"Antonio Lingnan", :avatar_url=>"missing.png", :given=>11, :late=>0, :wip=>2}

======== index 2 =======

{:full_name=>"Uland Nimblehoof", :avatar_url=>"missing.png", :given=>11, :late=>0, :wip=>2}

======== index 3 =======

{:full_name=>"kU", :avatar_url=>"missing.png", :given=>10, :late=>0, :wip=>2}

======== index 4 =======

{:full_name=>"Saadi Orlaf", :avatar_url=>"missing.png", :given=>11, :late=>0, :wip=>2}

Out Put of stats_array after Each-Do loop

======== stats_array =======

{:full_name=>"Saadi Orlaf", :avatar_url=>"missing.png", :given=>11, :late=>0, :wip=>2}

{:full_name=>"Saadi Orlaf", :avatar_url=>"missing.png", :given=>11, :late=>0, :wip=>2}

{:full_name=>"Saadi Orlaf", :avatar_url=>"missing.png", :given=>11, :late=>0, :wip=>2}

{:full_name=>"Saadi Orlaf", :avatar_url=>"missing.png", :given=>11, :late=>0, :wip=>2}

{:full_name=>"Saadi Orlaf", :avatar_url=>"missing.png", :given=>11, :late=>0, :wip=>2}

Upvotes: 0

Views: 88

Answers (1)

m3characters
m3characters

Reputation: 2290

Try to declare pUser only inside the .each loop. My guess is since you're not duplicating the object you're just pushing references to the object on to the array, hence it gets updated to the last one always.

stats_array = []

userProject = UserProject.find_by(project_id: params[:projectId], user_id: params[:userId])

if userProject && userProject.project.present?

  projectUsers = userProject.project.users.where(role_id: 1..3).page(params[:page]).per(5) 
  projectUsers && projectUsers.each do |pu|

    pUser = {}
    pUser[:full_name] = pu.full_name
    pUser[:avatar_url] = pu.avatar.url(:medium)
    pUser[:given] = UserTask.where(to_user: pu.id).joins(:task).count
    pUser[:late] = UserTask.where(to_user: pu.id).joins(:task).where(:tasks => {end_date: Date.today.beginning_of_day..Date.today.end_of_day}).count
    pUser[:wip] = UserTask.where(to_user: pu.id).joins(:task).where(:tasks => {state: @@task_wip_code}).count
    puts "=============================="
    puts pUser # outputs correct details
    puts "=============================="
    stats_array.push(pUser)

  end
end

Upvotes: 2

Related Questions