0

While implementing a DBMS similar to Chadwick database, I'm encountering lots of similar codes like below (Please refer to the upper link if you think the database design itself is wrong.)

Setting values

self.away_lineup1_batter = player if player.id === away_lineup1_batter_id
self.away_lineup2_batter = player if player.id === away_lineup2_batter_id
self.away_lineup3_batter = player if player.id === away_lineup3_batter_id
self.away_lineup4_batter = player if player.id === away_lineup4_batter_id
self.away_lineup5_batter = player if player.id === away_lineup5_batter_id
self.away_lineup6_batter = player if player.id === away_lineup6_batter_id
self.away_lineup7_batter = player if player.id === away_lineup7_batter_id
self.away_lineup8_batter = player if player.id === away_lineup8_batter_id
self.away_lineup9_batter = player if player.id === away_lineup9_batter_id

or

Getting values

# Using jbuilder gem.
json.pos2_fielder do
  json.partial! 'players/simple_hash', locals: {data: data.pos2_fielder}
end unless data.pos2_fielder.nil?
json.pos3_fielder do
  json.partial! 'players/simple_hash', locals: {data: data.pos3_fielder}
end unless data.pos3_fielder.nil?
json.pos4_fielder do
  json.partial! 'players/simple_hash', locals: {data: data.pos4_fielder}
end unless data.pos4_fielder.nil?
json.pos5_fielder do
  json.partial! 'players/simple_hash', locals: {data: data.pos5_fielder}
end unless data.pos5_fielder.nil?
json.pos6_fielder do
  json.partial! 'players/simple_hash', locals: {data: data.pos6_fielder}
end unless data.pos6_fielder.nil?
json.pos7_fielder do
  json.partial! 'players/simple_hash', locals: {data: data.pos7_fielder}
end unless data.pos7_fielder.nil?
json.pos8_fielder do
  json.partial! 'players/simple_hash', locals: {data: data.pos8_fielder}
end unless data.pos8_fielder.nil?
json.pos9_fielder do
  json.partial! 'players/simple_hash', locals: {data: data.pos9_fielder}
end unless data.pos9_fielder.nil?

Copying and pasting 9 rows of codes aren't really a big deal but I think there could be a better solution for this. Any suggestion?

Lee Han Kyeol
  • 2,371
  • 2
  • 29
  • 44

2 Answers2

1

The primary suggestion: use arrays in Ruby and properly normalised database tables. Instead of having pos2_fielder, pos3_fielder... in one table, you should have a table with position property. (I can't say anything more specific as I do not know what your database looks like precisely, aside from "bad").

To answer the literal question:

1.upto(9) do |num|
  if player.id === send(:"away_lineup#{num}_batter_id")
    send(:"away_lineup#{num}_batter=", player)
  end
end
Amadan
  • 191,408
  • 23
  • 240
  • 301
  • I certainly do appreciate your suggestion. (I didn't even know about `send`. Thanks.) If you see [the link](http://chadwick.sourceforge.net/doc/cwevent.html) that I provided, you can grasp the idea of what `lineup#{num}` is. – Lee Han Kyeol Oct 15 '15 at 01:57
  • 1
    `send` is the ultimate swiss army knife for Ruby, as it is even able to invoke private methods on other objects (use with care :p). About the database... again, I am not 100% sure what you are doing, but if you can't choose your DB format, I would rather have a pair of conversion methods that translate the literal database format into something more pleasantly usable. The bottom suggestion should work even if you decide your current way of access is good enough / faster / whatever. – Amadan Oct 15 '15 at 02:02
1

what's wrong with

 [1,2,3,4,5,6,7,8,9].each { |i| eval("self.away_lineup#{i}_batter = player if player.id === away_lineup#{i}_batter_id" }
jjk
  • 536
  • 7
  • 15
  • What's wrong? [`eval`](http://stackoverflow.com/questions/1902744/when-is-eval-in-ruby-justified), for one thing. :P It is insecure in general (not here), and it is *slow*. – Amadan Oct 15 '15 at 01:45
  • The question isn't about database design or naming conventions. It's about utilizing ruby to help handle the naming convention the user put in place for whatever reason. – jjk Oct 15 '15 at 01:49
  • If you read my answer, there is a solution for the literal question as well - without `eval`, which should be avoided whenever possible, as it invokes the Ruby parser. Even `[1, 2, 3, 4, 5, 6, 7, 8, 9]` is needlessly verbose and uses more memory than needed. – Amadan Oct 15 '15 at 01:50
  • yeah, I saw that. I think parts of your answer are good, especially the Primary Suggestion. – jjk Oct 15 '15 at 01:54