Peter Carter
Peter Carter

Reputation: 2728

Dynamic variable names in Ruby (on the Rails)

I need to store character stats to a MySQL database using the Ruby on the Rails framework. It seems that I can't use arrays in my database without transitioning to PostgreSQL, which I am not able to do at present. So, I thought that dynamic variable names would be the key but I'm not sure how to create them. At the moment my code looks like this:

class CreateInventories < ActiveRecord::Migration
  def change
    create_table :inventories do |t|
      t.string :user_name
      t.string :char_name
      t.string :char_item1
      t.string :char_item2
      t.string :char_item3
      t.string :char_item4
      t.string :char_item5
      t.string :char_item6
      t.string :char_item7
      t.string :char_item8
      t.string :char_item9
      t.string :char_item10
      t.string :char_item11
      t.string :char_item12
      t.string :char_item13
      t.string :char_item14
      t.string :char_item15
      t.string :char_item16
      t.string :char_item17
      t.string :char_item18
      t.string :char_item19
      t.string :char_item20


      t.timestamps null: false
    end
  end
end

Obviously this is horrible. Can anyone tell me a way of sorting it out so that it doesn't use 20 lines of code to create what really should only be one variable?

Upvotes: 0

Views: 676

Answers (2)

pcm
pcm

Reputation: 319

I would recommend normalizing your data model. Although your structure would work for the first 20 items in an inventory, if you want to add another inventory slot you don't want to be doing a database migration.

If you stored the item data in a separate table, you could have an InventoryItems table that functions as a join table.

class CreateInventories < ActiveRecord::Migration
  def change
    create_table :inventory_items do |t|
      t.references :user
      t.string :inventory_slot
      t.references :item
    end
  end
end

This way, you can make your characters' inventory arbitrarily large without having to do any database migrations.

Upvotes: 1

the Tin Man
the Tin Man

Reputation: 160631

This is untested, but is the basis for generating strings or symbols dynamically:

create_table :inventories do |t|
  t.string :user_name
  t.string :char_name

  20.times do |i|
    t.string "char_item#{ 1 + i }".to_sym
  end

  t.timestamps null: false
end

Upvotes: 3

Related Questions