-1

I need to nornalize some data, and i am new to backend/database programming, so this might be pretty obvious but I've searched and couldn't find anything.

I have an 'empires' table. Each empire can be 'civilization' one of the following:

- British
- French
- Dutch
- Ottoman
- Spanish

Right now, the empires table contains a column of type VARCHAR(255) called civilization and that's where the one of the above strings is stored.

Now ofcourse, later I realized that it's not very scalable and not a good idea, so what I decided to do was to create another table called civilization which contains 2 columns, id and string which contains it's name.

My questions now is, how do I ensure, for example, that all 'British' empire will point to the exact same row in civilization table ?

0xSina
  • 20,973
  • 34
  • 136
  • 253
  • do you mean you would have multiple `"British"` empires, and every of them points to the same `civilization`? that would be Many-to-One association, am I right? – PeterWong Dec 10 '12 at 05:52

1 Answers1

0

UPDATED 2: 1 to many association

class Empire < ActiveRecord::Base
  attr_accessible :name
  belongs_to :civilization
end

class Civilization < ActiveRecord::Base
  attr_accessible :name
  has_many :empires
end

british = Civilization.new(:name => 'British')
british.empires.build(:name => 'Britian')
british.empires.build(:name => 'India')
british.save

india = Empire.where(:name => 'India')
britain = Empire.where(:name => 'Britain')

puts india.civilization == britain.civilization # => true
puts india.civilization.inspect                 # => <Civilization:0x04121231 @name="British">
puts india.civilization.empires.inspect         # => [ <Empire:0x0123443 @name="Britain">, <Empire:0x0124543 @name="India"> ]

Your gonna need a civilization_id on your empires table to store the id from your civilizations records.

strider
  • 5,674
  • 4
  • 24
  • 29
  • in general: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many – strider Dec 09 '12 at 06:34
  • Yes, but how do I ensure all empires that are 'Britain' point to the same civilization 'Britain'??? that was my question – 0xSina Dec 10 '12 at 02:46
  • Ah it seems like empires and civilizations have a 1 to 1 association, is this true? To answer your question, you can use the `before_create` hook to copy the name from one to the other upon creation. In what order do these get created? Empire then Civilization, Civilization then Empire, both at the same time, or all of the above? – strider Dec 10 '12 at 04:39
  • While it would seem like a perfect idea to use `name` instead of `id` as the primary key, but thats [not a good idea](http://stackoverflow.com/questions/1200568/using-rails-how-can-i-set-my-primary-key-to-not-be-an-integer-typed-column) because its been known to break ROR – strider Dec 10 '12 at 04:43
  • It's not a 1:1. An empire can only have 1 civilization, a civilization can have many empires. I just want tensure that all empires of type Britain point back to the exact same civilization. – 0xSina Dec 10 '12 at 13:41
  • then my first answer (which i reposted) should be what you are looking for. `india.civilization == britain.civilization`. Essentially, the `has_many` statement does all the work. – strider Dec 10 '12 at 17:09