2

This code is ugly, how to do better?

todos = Todo.all

@todos_1 = Array.new
@todos_2 = Array.new
@todos_3 = Array.new

todos.each do |doc|   
  if doc.category == nil 
    @ntodos_1 << doc 
  end
  if doc.category == "something" 
    @todos_2 << doc 
  end
  if doc.frame == "whatever" 
    @todos_3 << doc 
  end
1
  • What should happen if doc.frame == 'whatever' && doc.category == 'something'? Can you please provide a proper specification of what the code should be doing, preferably including test cases? Commented Aug 30, 2011 at 11:21

3 Answers 3

3

You can use Todo.group("category").order("category") to organize the result set and then loop over it, knowing that when category changes you are at the next grouping.

Alternatively, it might be useful to create scopes for the Todo model:

class Todo < ActiveRecord::Base
  scope :something, where(:category => "something")
  scope :whatever, where(:category => "whatever")
end

This would allow you to assign the results to instance variables instead of iterating over all results within your controller:

@something = Todo.something
@whatever = Todo.whatever
Sign up to request clarification or add additional context in comments.

2 Comments

That is nice! However it would send two db requests in that case. What if I would want to send just one db request and do the splitting in ruby?
The first part of the answer would give you a solution for that. Basically, you need to keep a reference to the previous iteration to compare against. When they don't match, you're at the next category.
1

Complementing the existing answer, let's assume you are working with "normal" Ruby objects, not a ORM:

todos_by_category = todos.group_by(&:category)

To be used:

>> todos_by_category["some_category"]
#=> [todo1, todo2, ...]

1 Comment

The scope solution mentioned above is handy. I was exploring Ruby and your answer is what I was looking for. Thanks!
0

At least the first two if's could be combined in one case:

todos.each do |doc|   
  case doc.category 
    when nil 
      @ntodos_1 << doc 
    when "something" 
      @todos_2 << doc 
  end
  if doc.frame == "whatever" 
    @todos_3 << doc 
  end      

You also know elsif? }

Comments

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.