From: "S. Potter" Date: 2008-02-10T03:13:34+09:00 Subject: Re: Comparing Active Record VS Datamapper...? > Steve wrote: > From my perspective, writing DDL is the most certain way to get what > you want. But it's a mental context switch that not everyone wants to > make regularly. I have never had a problem getting AR migrations to produce the DDL I need. For database specific options you can define the :options parameter to pass into the relevant migration method (e.g. create_table, etc.). Also standard parameters like :limit, :null, :primary, etc. are available and aren't used enough in my experience by Rails developers. In addition to this I have internally developed AR migration extensions where I can simplify things in a more convenient way just by extending the relevant AR adapters and in the process reduce human error considerably and thus produce a more consistent DB schema: --- # pastie: http://pastie.caboo.se/private/2jrjnodsjsxxgi4stbjmg class << self # yes I use this Ruby idiom, perhaps a bit too much:) up create_lookup_table :countries # OR add_foreign_key :users, :country_id #, :table => :not_obvious_table_name # OR end down drop_lookup_table :countries # OR remove_foreign_key :users, :country_id #, :table => :not_obvious_table_name end end --- In the above example "create_lookup_table" creates a specific type of table that usually has an :id, :code (which is unique), :name, where :code has a unique index declared on it. This is just a small sample of extensions I have internally developed for specific needs, but the point is that customization of AR migrations is fairly painless for a Ruby developer, which yields a much lower incidence of human error and schema inconsistencies than directly writing DDL and streamlines the process of creating consistent schemas with little mindset switching. > Steve also wrote: > But it turns out there are some migrations that can't really be > reversed, such as removing columns. You can add the columns back > in but the data can't easily be reconstructed. Yes, but this is why AR migrations allow you to declare in the down migration that it is an irreversible migration by raising an IrreversibleMigration exception, if you feel that is necessary for project sanity. Now on the general topic of DataMapper vs. ActiveRecord. First let us consider the original idea behind both. Both of these Ruby libraries are based on Fowler's enterprise architecture patterns of the same name. However, the Ruby library DataMapper doesn't appear to be written in exactly the same vain as Fowler's pattern. The Ruby DataMapper library promotes the use of the DataMapped objects *as* Domain Objects, which is different to Fowler's pattern recommendation that is to use a Data Mapper to separate the in-memory domain object from it's database representation. ActiveRecord (the Ruby library) is consistent with Fowler's definition of Active Record (the PofEA), except that Ruby metaprogramming is able to hide so much of the database lookup code that the design pattern's documented disadvantage (of not being useful for complex domain object logic) doesn't apply as much. I feel this difference is much overlooked and needs stating. I have only used AR (Ruby) on production projects and only played with DM (Ruby) on personal projects, so I am not able to give an in-depth comparison of real world usage or performance. However, in theory a library that follows Active Record pattern principles would be more beneficial to use when tables more directly correlate to objects (i.e. an isomorphic schema). When mapping table attributes into many object instances you may find libraries using a Data Mapper pattern less complex and more expressive. However, the primary advantage of Fowler's Data Mapper pattern requires that you separate the Data Mapper class from the Domain Object class. Of course this is complicated by the fact that in Ruby orthogonal features can be added using metaprogramming, which wasn't considered when Fowler wrote the PoEA book as he was was heavily into non-metaprogramming-capable static languages at the time. It appears that if DataMapper (the Ruby library) is able to sufficiently hide enough database logic in more complex business logic scenarios, then the DM library might be more beneficial to use when using a legacy database schema where you are not able to create primarily isomorphic relationships between class attributes and table columns, whereas AR would be a slam dunk and simpler to use in isomorphic schema scenarios. HTH, Susan --- @blog: http://snakesgemscoffee.susanpotter.net -- Posted via http://www.ruby-forum.com/.