Again, this magic works by using certain code conventions. By saying 'belongs_to :company' Rails expects to find an ActiveRecord model named Company, which in turn expects a table called Companies. The relationship between the two is figured out by the 'belongs_to' statement, which expects to find a foreign key column in the Employee table, with the name of the table it points to. The name of the foreign key in this example would be 'company_id'.
This is only one example of a possible relationship, the others are :has_one, :has_many, and :has_and_belongs_to_many. They all work using the same principle, the convention of using primary and foreign keys with a certain name. All the metadata is extracted at runtime from the database tables and there is no explicit mapping present. It is therefore not possible to generate automatically a database schema like for example Hibernate does, a well-known object-relational mapping framework in the Java world.
That doesn't mean there is not any help at all from ActiveRecord to manage your database(s). There are two classes that help you: ActiveRecord::Schema, a class that allows you to define your table and ActiveRecord::Migration, a class that helps you manage the evolution of your schema. Instead of writing SQL DDL statements to create your database, you can describe your tables or modifications in Ruby using a domain specific set of classes and methods, just like we defined relationships between various tables. Lets see how we could define our 'employees' table using a Schema class:
create_table :employees do |t|
t.column :name, :string, :null => false
t.column :birthdate, :date
t.column :email, :string
add_index :employees, :name, :unique
As you can see the domain specific language used here is so clear, that no real explanation is needed: a table called 'employees' is created, a few columns and an index are defined. Since this is just plain Ruby, the database creation is completely database independent and supports every database that Rails supports, except for DB2.
class AddSSNToEmployees < ActiveRecord::Migration
add_column :employees, :ssn, :string
remove_column :employees, :ssn
This class has two methods: 'self.up' and 'self.down'. The first one is used when upgrading to a new version of the database, the latter for downgrading if needed. Again, you don't need to understand Ruby at all to see what is going on here, a new table called 'employees' is created and some columns are added. A 'schemainfo' table is automatically created where the current version of the database is stored. The default Rails installation puts a script in your project directory that executes all migrations in the correct order and brings your database up to date. Using Rails Migrations alleviates the pains often found when pushing changes to multiple development databases and other environments like test or production that may be multiple versions behind.
Needless to say, this is only a small portion of what you can do with ActiveRecord, but it did demonstrate the most important aspects. Conventions and a domain specific macro language let you describe your models and express relationships between them. When you can't adhere to these conventions due to external constraints (an existing database schema for example) or whatever the reason is, you can override this wherever you want to.