6
\$\begingroup\$

I have a simplified model that looks like this:

class Player < ActiveRecord::Base
  has_many :picks

  def pick_for_game(game)
    id = game.instance_of?(Game) ? game.id : game
    pick = picks.find {|pick| pick.game_id == id}
    if !pick
      pick = picks.build(:game_id => id)
    end
    pick
  end
end

The pick_for_game method usually is called a bunch of times when an action is executed. What would be a good way to make this code work efficiently with a list of games?

\$\endgroup\$
7
\$\begingroup\$

You can use find_or_initialize_by dynamic finder, see a guide here

This would be equivalent to your code:

def pick_for_game(game)
  game_id = game.instance_of?(Game) ? game.id : game
  picks.find_or_initialize_by_game_id(game_id)
end

Hope it helps you!.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ This is why I love ruby and rails. You can write such elegant and simple code. \$\endgroup\$
    – Yads
    Mar 31 '11 at 14:21
3
\$\begingroup\$

Expanding on @jpemberthy: Shouldn't we duck type?

def pick_for_game(game)
  game = game.id if game.respond_to? :id
  picks.find_or_initialize_by_game_id(game)
end

or be brazen:

def pick_for_game(game)
  picks.find_or_initialize_by_game_id(begin game.id rescue game end)
end
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.