Damn, that new release of Hobo reminds me: those guys have got some nice looking migrations. Let’s take it a step further. Let’s bring sexy back.
Let’s turn this:
class UpdateYourFamily < ActiveRecord::Migration create_table :updates do |t| t.column :user_id, :integer t.column :group_id, :integer t.column :body, :text t.column :type, :string t.column :created_at, :datetime t.column :updated_at, :datetime end def self.down drop_table :updates end end
Into this:
class UpdateYourFamily < ActiveRecord::Migration create_table :updates do foreign_key :user foreign_key :group text :body string :type timestamps! end def self.down drop_table :updates end end
Using this:
SVN:
$ ./script/plugin install \ svn://errtheblog.com/svn/plugins/sexy_migrations
Piston:
$ piston import svn://errtheblog.com/svn/plugins/sexy_migrations \ vendor/plugins/sexy_migrations
That’s it. It works with them newfangled Independent Migrations and is 100% backwards compatible. Keep your old migrations, sex up your new migrations. But, be careful: it’s real hard to go back to the ‘old way’ of writing migrations once you start getting your sexy on. You’ve been warned.
Bugs!
You heard that Lighthouse launched, right? Right. From now on, any bugs found in any Err plugins should be reported at the Err plugins Lighthouse project. You can jump straight to creating a new ticket if you’d like. (Just make sure to include the name of the plugin you’re reporting a bug for.)
Oh, and speaking of bugs: you may want to follow Err on Twitter. We’ll be using it to post updates about our projects and plugins and blogs, oh my. Oh yeah.
very sexy indeed.
Does the foreign_key create actual referential integrity like http://www.redhillonrails.org/#foreign_key_migrations ?
sweet :) Well done man.
I really like the syntax of this, but wanted to make you aware of a recent patch that has a similar syntax, but relies on a method_missing hack, of sorts. The patch isn’t nearly as complete as this, but thought I’d pass it along.
Ted: This doesn’t create actual foreign key constraints, but I don’t see why this plugin couldn’t work in harmony in the redhillonrails one.
Damn you err-the-blog man! I was going to add that to Hobo. You’ve totally stolen my thunder ;o)
One query – what’s special about ‘timestamps!’ that it should have a bang on the end?
Tom: Nothing too special. It’s aliased as timestamps, auto_dates, and auto_dates!—you can use whichever you’d like. I like the bang because it does two things at once, things you can do yourself, so it reminds me that it’s ssssspecial.
That is very cool. Will have to try it out.
Oh yeah, where’s the “self.up” method definition? Was it left off by accident?
The svn repository is asking me for a password…
I’ll be in my bunk.
My greatest wish for migrations would be for me to specify what I normally add for the “self.up” method, and for the “self.down” method to be automatically generated.
If it were coded to understand what the reversal method was for each add/create method, and actions were run in reverse order to how they were defined, I think alot of it could be automated.
Of course there are some things that cannot be reversed, which is where an exception needs to be thrown, but I still think most of what we do in migrations could be DRYed up.
@Dan Kubb: the TextMate Rails bundle includes a macro that understands how to reverse many of the basic migration steps, and fills in the corresponding self.down line as you type the self.up line. If you’re on Windows, e-texteditor.com may support this.
Point being, you might need to write this yourself. With TextMate so popular in the Rails world, I doubt the core team is particularly feeling your pain.
Dan: I hear ya—I usually do something like this in my initial migration.
While this looks really cool, I don’t know that I could give up all of the handy TextMate snippets that I use when creating migrations. Hmmm…maybe I will need to create some new TextMate snippets :-)
I’m not sure why you are talking about bringing sexy back.
Sexy never left.
Well guys, if you check out some of the chatter going on over here:
http://blogs.sun.com/tor/entry/ruby_screenshot_of_the_week6
You’ll see that a real ERD model tied into migrations so that a graphical back and forth flow would be much sexier than any textual migration… ;)
It bears mentioning that the down-generating functionality is also present in vim’s Rails package. But then I suppose at the end of the day it’s less about the fact that our editors can reduce the pain (the Java folks can say that, too), and more about not needing the editors to help us repeat ourselves to begin with. Admittedly, migrations are a one-time thing, but still…
Purely thinking aloud, it’d be nice if, when Rails went to reverse a migration, it checked for a `down’ method. If present, it assumes that the entire reverse migration is in there. If not present, then it changes the meaning of the various potential `up’ methods (e.g., create_table and the add_column, etc, calls) to mean the opposite of what they mean (through some aliasing magic and other voodoo, for example). Now, problems obviously come up with remove_column calls, for example, since the type information isn’t provided when you remove a column. Still, assuming all of the database stuff is in a migration somewhere, you could try doing a scan of the migrations to find where that column is defined, for example.
This is all a lot of extra work, of course, but it would certainly be nice.
Most of my migrations have down methods that look like mirror images of the up method.
I think for something like this to work you’d specify whatever you normally do in the up method, and behind the scenes it would generate the up method automatically, and reverse (ordering AND method calls) everything for the down method.
As Antonio mentioned the main sticking point would be if in your “up” method you wanted to remove a column, you’d need a way to specify enough information so the down method could create the column when reversing the migration.
Actually what would be nice is if the remove methods took the same arguments as the add/create type methods, and the system made it so you couldn’t remove something unless the arguments provided would allow a exact restoration of whatever you were removing. I hope that made sense. In a way it would sort of be like saying: “remove this column, but only if the column has these precise attributes”.
This plugin looks great.
But, does it sexify update migrations?
i.e. add_column :groups, :lat, :float
Nice! I added a small patch that allows an option of :ref => :reftablename to the foreign_key, this will create a foreign key constraint for that column to the named table, which works for both postgresql and mysql, If you would like the patch let me know where to send it.
Thanks
Jim: Bugs to Lighthouse please.
Ok I’ll try, unfortunately Lighthouse doesn’t work with a Firefox browser, so I’ll have to find ie somewhere I guess (hard as I use Linux!)
I have filed a patch to lighthouse which also adds indexes.
eg string :alias, :idx => {:unique => true} # creates a unique index on alias
I’m using it right now and feel much sexier.
Do you think there is any value in abstracting other elements?
For example,
would produce
topfunky: Yep, funny enough I added a polymorphic method before you made your comment. inheritable is now in there. Check my tweet.
Have your “Sexy Migrations” been integrated into Hobo or have you discussed it with Tom Locke? Seems like this might be a nice integration.
here the patch for mail line rails: http://dev.rubyonrails.org/changeset/6667
So the 6667 changes are nice – but no indices and no foreign keys get created. So I modifed the sexy migrations to have both:
http://err.lighthouseapp.com/projects/466-plugins/tickets/5-add-indexes-to-sexy_migrations#ticket-5-5
http://pastie.caboo.se/63388
Cheers, Andrew
So sexy migrations made it to the rails edge trunk, but why didnt foregin key make it?
@Martin: I would bet we’ll never see “foreign_key” make it into edge rails (due to a belief by some core members that foreign keys are unecessary). However I bet what would be accepted is a patch that adds “belongs_to”, which basically just created an integer field (without creating a foreign key) pointed at the foreign table, named #{table_name}_id.
The reason I think this is that we’ve seen some recent changes by DHH to add belongs_to/has_many type relations in routing. Its not too much of a stretch to bring the same general syntax to table migrations.
The beauty of this approach is that plugins can be created that override the standard belongs_to method, and creates a real foreign key when possible.
I just wanted to let you guys know that I have created a TextMate bundle for the Sexy Migrations plugin, which is one of my favorites and gets included in ever new project I start.
You can get the Sexy Migrations Bundle at http://www.railsjitsu.com/blog/project-releases/sexy-migrations-textmate-bundle/ and I have included instructions for installing it.
Thanks Chris and err.the_blog! You guys are my favorite Ruby on Rails blog!
Why not add the support for the additions of foreign key constraints as well to the database as the redonrails plugins are doing?
Chime in.