I wouldn't go for this route when trying to convince one.

IMO database migration and the ORM are different concerns and we should actually use the single responsibility principle with regards to them.

For example, I prefer to maintain my database migrations in a different project using standalone-migrations:

https://github.com/thuss/standalone-migrations

There are advantages and disadvantages using this approach, but I still think it is a better option than integrating the migrations directly in the application.

Disadvantages:

1- rails g model user email password_hash role:references

This wouldn't be much useful if migrations are not integrated. This could be worked around in the standalone-migrations if they included some generators to easy migrations generation.

The generated model class itself is so short that it is pretty fast to create it by hand. With ActiveRecord it is "class MyModel < ActiveRecord::Base; end". Just replace with Sequel::Model for Sequel.

2 - application-specific classes can't be used inside migrations (is this really a disadvantage?)

Some people like the idea of updating some data in the database during a migration by using the ORM itself inside the migrations.

While this can be handy sometimes, it can create some issues too.

For instance, your migration is now relying on your application code by the time you created the migration.

After a while that code may no longer exist or do a different thing, so this is pretty dangerous.

I've already experienced some issues in open-source projects where I couldn't run a migration because the code inside earlier migrations would no longer run.

The solution provided by Rails is to use "rake db:setup" for fresh databases, but what if you need to run several migrations because you already have a database, but the code has changed in such a way that some of the earlier migration code won't run anymore?

That is one of two of the strongest reason I want to keep my migrations in a separate project. Doing that you'll be assuring that no application-specific domain code will be part of the migrations.

3 - You can't know what was the specific database version in use within some commit.

Working around this limitation is pretty simple if you're using Git. Just use your migrations project as a submodule and every time your classes rely on a different database state, update the commit the submodule points to.


Advantages:

I've talked already about most of them. Here are some more:

1 - You don't risk being unable to migrate or rollback your database due to some issue in your code

I want to be sure that I'll be able to quickly run my migrations or rollback the database even if my application won't boot for some reason, like a bad initializer that relies on some network connection that is not available or anything else. I want to just keep it simple.

2 - You can have different applications in possibly different languages interacting with your database while having a single separate place to store the migrations.


Back to the subject:

I've tried to convince you not to argue about defining the properties inside the models to avoid duplication of code in migrations because they should be really isolated from each other from my point of view.

Now, I'd like to share that I like the ability to quickly see what are the column names for some domain by looking at its source-code. Your solution provides that, but it is not the only way to achieve this goal.

Some people might want to document such columns by using the attr_protected and attr_accessible methods. I don't agree that protection against mass-assignment is a responsibility of the models, hence I don't agree with the default config.active_record.whitelist_attributes = true in application.rb. They should be handled by the controller in a MVC or Model2 architecture.

But there is a simple solution that solves this issue for me (this example assumes Sequel, since that is my ORM of choice):

rails r "puts User.columns.join ', '"

Then it is just a matter of replacing the comment in my classes when the table changes (I always omit 'id'):

class User < Sequel::Model
    # columns: email, password_hash, role_id
    ...
end


So, I'd like to ask you how do you think your proposal could help me if I were using ActiveRecord instead of Sequel, since I'd use the same ideas with AR as well.

Cheers,
Rodrigo.

Em 09-05-2012 07:29, mcasimir escreveu:
No other answer? I do not have you convinced yet then .. I hope that does not bother you if I try again.

About 'this is not active record': with ruby ActiveRecord you have improved the pattern yet mixing it with STI and supporting associations with macros. About 'this is duplicated code': what about STI? where in the migrations code or in schema.rb or even in the database itself persist the information that an attribute belongs to a children class and not on the whole hierarchy classes? And where in the migration code is

eg
class Content < AR::Base
class Article < Content
class Video < Content

create_table content
   add_column :title ..
   add_column :url ..
   add_column :text ..

Here Video instances will respond to :text, and Article will respond_to :url without batting an eye. moreover even in the schema.rb the 'contents' table schema is all you can find.. perhaps this is a consequence of ActiveRecord not yet supporting STI very well.

This can't be the same of:

class Content < AR::Base
   field :title

class Article < Content
   field :text

class Video < Content
   field :url

there is a very important information here: text is something that belongs to Article, and url is something that belongs to Video. This way you could also enforce that Video should not respond to 'text' and Article should not respond to 'url'. This is nothing you can express with migrations! Migrations are only a history to keep track of changes you made to database. They are not good to express the *logical *structure of the application domain.

All that i ask to you is what you think about that? But answer without focusing on my purposed solution, but in a more abstract way. I think the topic of discussion here is not whether to make a change ​​or not to ActiveRecord .. I probably said bad in this regard.. but I'd like to know what you think of this lack.. first of all.. do you think this is so? have you ever thought of it?

For me this was the first thing I noticed when i approached ruby on rails from java world. This leak significantly restricts the ability to refactor, mantain, document and reuse code, in other word a weakness in dealing with changes over time. Why do not just try to make things better? You have just done it in past, em i wrong?

Maurizio --

--
You received this message because you are subscribed to the Google Groups "Ruby on 
Rails: Core" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-core?hl=en.

Reply via email to