I'm incredibly proud to present the first public release of Active 
Record -- an implementation of the ActiveRecord pattern for 
object-relational mapping. I've entitled this release Three-Quarters to 
reflect the fact that Active Record has been in production use on 
Basecamp for more than three months and used during the many months of 
development before that. Additionally, it's been used by around five 
beta testers in a number of different projects. So even though I'm not 
ready to declare it 1.0 out of the gates, it is indeed a solid release.

It also marks the first step towards releasing the web-application 
framework Rails, which I've been hyping and talking about for some time 
now. Active Record is the model part of Rails and contains around 
two-thirds of the code in the framework. So if you want to get ready 
for making Rails applications, it's a good idea to familiarize yourself 
with Active Record.

Further more, I'd like to extend my thanks to Luke Holden, Jamis Buck, 
Aredidel, Guan Yang, and Lau TéÓnskov for helping me make this release 
a reality. All your help and suggestions have been much appreciated!

Below is a snapshot of the README. Find more information and links to 
downloads on the official website at 
http://activerecord.rubyonrails.org/ and on the API site at 
http://ar.rubyonrails.org/

/ David Heinemeier Hansson


== Active Record -- Object-relation mapping put on rails

Active Record connects business objects and database tables to create a 
persistable
domain model where logic and data is presented in one wrapping. It's an 
implementation of the object-relational mapping (ORM) pattern by the 
same name as described by Martin Fowler:

   "An object that wraps a row in a database table or view, encapsulates
        the database access, and adds domain logic on that data."

Active Records main contribution to the pattern is to relieve the 
original of two stunting problems: lack of associations and 
inheritance. By adding a simple domain language-like set of macros to 
describe the former and integrating the Single Table Inheritance 
pattern for the latter, Active Record narrows the gap of functionality 
between the data mapper and active record approach.

A short rundown of the major features:

* Associations between objects controlled by simple meta-programming 
macros.
    class Firm < ActiveRecord::Base
      has_many  :clients
      has_one   :account
      belong_to :conglomorate
    end

* Aggregations of value objects controlled by simple meta-programming 
macros.
    class Account < ActiveRecord::Base
      composed_of :balance, :class_name => "Money",
                  :mapping => %w(balance amount)
      composed_of :address,
                  :mapping => [%w(address_street street), 
%w(address_city city)]
    end

* Validation rules that can differ for new or existing objects.
    class Post < ActiveRecord::Base
      def validate # validates on both creates and updates
        errors.add_on_empty "title"
      end

      def validate_on_update
        errors.add_on_empty "password"
      end
    end

* Callbacks on the entire lifecycle (instantiation, saving, destroying, 
validating, etc).
    class Person < ActiveRecord::Base
      def before_destroy # is called just before Person#destroy
        CreditCard.find(credit_card_id).destroy
      end
    end

* Observers for the entire lifecycle
    class CommentObserver < ActiveRecord::Observer
      def after_create(comment) # is called just after Comment#save
        NotificationService.send_email("david / loudthinking.com", comment)
      end
    end

* Inheritance hierarchies
    class Company < ActiveRecord::Base; end
    class Firm < Company; end
    class Client < Company; end
    class PriorityClient < Client; end

* Direct manipulation (instead of service invocation)

   So instead of (Hibernate example):

      long pkId = 1234;
      DomesticCat pk = (DomesticCat) sess.load( Cat.class, new 
Long(pkId) );
      // something interesting involving a cat...
      sess.save(cat);
      sess.flush(); // force the SQL INSERT

   Active Record lets you:

      pkId = 1234
      cat = Cat.find(pkId)
      # something even more interesting involving a the same cat...
      cat.save

* Database abstraction for three different engines through simple 
adapters
    ActiveRecord::Base.mysql_connection(host, username, pass, database)
    ActiveRecord::Base.postgresql_connection(host, table, username, 
pass, database)
    ActiveRecord::Base.sqlite_connection(dbfile)

* Logging support for Log4r and Logger


== Philosophy

Active Record attempts to provide a coherent wrapping for the 
inconvenience that is object-relational mapping. The prime directive 
for this mapping has been to minimize the amount of code needed to 
built a real-world domain model. This is made possible by relying on a 
number of conventions that make it easy for Active Record to infer 
complex relations and structures from a minimal amount of explicit 
direction.

Convention over Configuration:
* No XML-files!
* Lots of reflection and run-time extension
* Magic is not inherently a bad word

Admit the Database:
* Lets you drop down to SQL for odd cases and performance
* Doesn't attempt to duplicate or replace data definitions