2
\$\begingroup\$

In the world of casinos, there are different types of games and jackpots. In this example, there are normal jackpots, multi-casino jackpots. I have a separate model for each of these. I need to display these in-line with each other. For instance, I'm grabbing the top 10 Caribbean Stud jackpots (Model: Jackpot), then displaying the top 10 multi-casino Caribbean stud jackpots (Model: MultiJackpot), and then displaying the top 10 Blackjack jackpots (Model: Jackpot) followed by the top 10 multi-casino Blackjack jackpots (Model: MultiJackpot).

I have two main problems with a chunk of code: I need to interpolate 2 different models in a specific order in a list.

This is a simplified example, but I have a similar scenario with slot jackpots where the models differ even more, which is preventing me from merging the models themselves.

Currently (and very inefficiently) I am doing 1 database call for each game and assigning it to its own instance variable for the view.

@caribbean_stud =                   Jackpot.where(:jackpot_game_id => JackpotGame.find_by_name("Caribbean Stud")).order("prize DESC").limit(10)
@multi_caribbean_stud =             MultiJackpot.where(:multi_jackpot_game_id => MultiJackpotGame.find_by_name("Caribbean Stud")).order("prize DESC").limit(10)
@progressive_blackjack =            Jackpot.where(:jackpot_game_id => JackpotGame.find_by_name("Progressive Blackjack")).order("prize DESC").limit(10)
@multi_progressive_blackjack =      MultiJackpot.where(:multi_jackpot_game_id => MultiJackpotGame.find_by_name("Progressive Blackjack")).order("prize DESC").limit(10)

In the view, I'm taking each instance variable and hard coding the order/interpolation.

The obvious 2 problem I'm running into:

  1. Many more database calls than necessary (I have over 30 games I'm doing this for)
  2. The view is not DRY (I could move the output for each model here into a partial, but I'm still hard coding the actual order & interpolation.)
\$\endgroup\$
  • \$\begingroup\$ Which version of Rails are you using? \$\endgroup\$ – Mohamad Jan 30 '15 at 22:54
1
\$\begingroup\$

First of all, the fact that you are mixing the use of Jackpot and MultiJackpot in this way suggests that they are really 2 different instances of a common, underlying concept. That calls into question whether they really need to be implemented as two different models. But that's up to you; you know the specifics of your own application.

As for removing the duplication, how about something along the lines of:

games     = ['Caribbean Stud', 'Progressive Blackjack']
@jackpots = games.map do |game|
  [Jackpot.where(...),
   MultiJackpot.where(...)]
end

You end up with an extra level of array nesting in the results, which could be eliminated with flatten(1). Or if don't mind adding your own methods to Array, I like to add one called mappend... I find it useful in almost every project. It it like map, but it appends all the returned arrays together to form a single array.

If you need the names of the games together with the results, you can games.zip(@jackpots) (you need the extra level of nesting for that one).

As for the DB calls, you'll find it hard to work around that while still using your nice Active Record query helpers. When DB performance is critical, I usually end up rolling my own SQL, perhaps using custom helpers added to model classes.

\$\endgroup\$

Your Answer

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