wachichornia
wachichornia

Reputation: 1188

Loop within loop within loop on Ruby on Rails

I want the user of my website to see the average of the answers (1 to 100) his friends have given him on different questions.

The final result of this method is an array with [question, sum of all answers, answer count]

3 tables are involved, each one with its own controller and model

I have a table of 'friendships', which stores users and friends.

Then there is a table of questions, which have just the questions and its ids.

Finally I have an answers table, which stores the friendship id, the question id and the answer given.

I found a way to do it (haven't tried it yet though): I look for the friendships of the user, then look for the answers given by each of these friendships, then going through each question to add it to a final array.

q_and_a = Array.new
friendships = Friendship.find_by_user_id(current_user.id)
friendships.each do |friendship|
    answers = Answer.find_by_friendship_id(friendship.id)
    answers.each do |answer|
        q_and_a.each do |array|
            question = Question.find_by_id(answer.question_id)
            if array[0] == statement.description
                array[1] = array[1] + answer.value
                array[2] = array[2] + 1
            else
                q_and_a << [ question.description, answer.value, 1 ]
            end
        end
    end
end

Its horrible, I'm hoping there is a better way to do this? Even more considering that the friendships table, as well as the answers table, are bound to have hundreds of thousands of records and will continue to grow

Edit As stated below, I had the associations set up but i was not using them! rookie mistake. The final working code is:

@q_and_a_them = Array.new
user_answers = current_user.friends.collect { |c| c.answers }.flatten
user_answers.each do |a|
  question = Question.find_by_id(a.question_id)
  if @q_and_a_them.empty?
    @q_and_a_them << [ question.description, a.value, 1 ]
  else
    @q_and_a_them.each do |q|
      if q[0] == question.description
        q[1] = q[1] + a.value
        q[2] = q[2] + 1
      else
        @q_and_a_them << [ question.description, a.value, 1 ]
      end
    end
  end
end

Plus the config on friendship.rb

has_many :relationships
has_many :answers, :through => :relationships

Upvotes: 3

Views: 226

Answers (2)

varatis
varatis

Reputation: 14740

Well

friendships.answers.each

should work, given that you have your relationships set up correctly (has_many, belongs_to)

Upvotes: 1

Pete
Pete

Reputation: 11495

The inner logic is a little more complicated, but you can reduce one level of depth using #flat_map:

friendships.flat_map { |f| Answer.find_by_friendship_id f.id }.each do |answer|
   q_and_a.each do |array|
     # Blah blah.
   end
end

Upvotes: 0

Related Questions