Tuesday, September 18, 2007

Gavin King on ActiveRecord

Referring to this ActiveRecord example:

class Person < ActiveRecord::Base  
   belongs_to :company  
end

class Company < ActiveRecord::Base  
   has_many :people  
end

Gavin says:

At this point, most developers are thinking um, ok, so how the hell am I supposed to know what attributes a Company has by looking at my code? And how can my IDE auto-complete them? Of course, the Rails folks have a quick answer to this question Oh, just fire up your database client and look in the database!. Then, assuming that you know ActiveRecord's automagic capitalization and pluralization rules perfectly, you will be able to guess the names of the attributes of your own Company class, and type them in manually.

Somehow, excitement about the Ruby language has warped their perceptions to such an extent that these people actually believe that this is a good thing!

Couldn't have said it better myself.

43 Comments:

Blogger Konstantin.Solomatov said...

BTW, What's your opinion about Ruby and ROR? Do you really think that it's possible to write really complex applications in this language?

1:45 PM  
Blogger Bob said...

Anything's possible if you put your mind to it, but I don't think RoR applications are very maintainable. I like type safety and the tools it enables.

2:01 PM  
Blogger Alex said...

Thank you!! For a while there I thought I was going crazy. A friend and I wanted to whip up a quick-and-dirty web app for a chess league he's running, and it seemed like a good chance to play with RoR. I spent 3 hours trying to figure out why the stupid framework was trying to access a table called "players" (plural) when I created an ActiveRecord for "player" (singular).

It wasn't until we unearthed the ancient tomes describing the secret naming conventions that we got it working. Yes, the auto-generating and scaffolding and what-not are cool and make for great demos, but there's a lot more to an industrial-strength application than generating a few pretty pages.

2:49 PM  
Blogger Michael Easter said...

Seems like perhaps "Convention over Configuration" might be (eventually?) replaced by a new catch phrase:

Annotation over confusion.

ps. FWIW, I have not used RoR and am neutral on it.

3:05 PM  
Blogger Anjan said...

hi all,

Didn't pragDave come up with a plug-in that would list the columns in the ActiveRecord class as comments ?

That way you can have the cake and eat it too ?

Thank you,

BR,
~A

3:05 PM  
Blogger Bob said...

Anjan, I think "the worst of both worlds" is a more accurate description.

3:08 PM  
Blogger matthew said...

Interesting point. But this isn't just a problem with Rails, or with Ruby.

I've written a fair amount of Python that auto-generates properties and converts invoked methods to internal dictionary lookups. Similar to a dynamic proxy in Java, just without the interface to bind to.

To my knowledge, there is no programmatic way of providing static information about classes that are dynamically enhanced in this fashion.

But also, to my knowledge, there's no way of writing code like this in Java.

I'll admit that writing a comprehensible Ruby API requires much more discipline than doing the same in Java -- but it's a burden I am happy to accept.

7:37 PM  
Blogger Bob said...

Writing the API isn't the problem. Without type checking, it's a lot harder for me to use your API.

7:42 PM  
Blogger Graeme Rocher said...

You could use Grails and GORM (http://grails.org/GORM). No annotations, proper static types, a mixed statically and dynamicly typed language (Groovy), built on Hibernate and no annotations.

Now that is the best of both worlds (I await flame from Bob) ;-)

2:27 AM  
Blogger Brian Ehmann said...

Just a thought...

What takes more time to learn, active record rules or hibernate configuration?

Don't get me wrong, I use hibernate at work and I love it, but I think some of the criticism of active record is a little over the top. Having to "learn the rules" of active record is no different than learning any other framework. I fail to see how that is a valid criticism.

In short, once you spend a little more than a few hours working with active record and rails, you will find it to be much more powerful than the simple examples given in these comments.

And one last thought, to see the schema your class maps to, open the class file in textmate and type "Ctrl-Shift-Command-S"

7:51 AM  
Blogger Bob said...

Brian, Java in general has a much higher learning curve than Ruby, especially when you consider generics and learning to get the most out of your tools. Java's type system pays off in long term maintainability and usability. You can take a shortcut and skip this step with Ruby, and you'll hit the ground running a little faster, but you'll also pay a continuous tax.

Nice TextMate tip.

9:56 AM  
Blogger Sony Mathew said...

Bob's comment regarding "continuous tax" sums up my thoughts exactly. Additionally type systems allow IDEs to help you maintain and refactor over the long run.

Thy dynamic-folks would say write and maintain comprehensive unit tests to achieve maintainability over the long run - which i can't argue with - i guess its feasible.

11:17 AM  
Blogger Unknown said...

It's funny how the dynamic typing folks don't want to count their unit tests as part of the code when they compare code compactness and expressiveness. Trading type declarations for unit tests is not a win. Especially when you give up tool assisted refactoring with it.

When I've raised this point I'm often told "you should be doing unit tests anyway" so this isn't extra code. The guidance to unit test anything and everything that might reasonabljy break plays out differently though, doesn't it.

11:57 AM  
Blogger Brian Ehmann said...

Concerning Refactoring in Ruby:

http://wiki.netbeans.info/wiki/view/RubyRefactoring

Yes, Tor Norbye is a coding machine.

12:27 PM  
Blogger Brian Ehmann said...

Something occurred to me that I believe is often forgotten. As developers, computer languages are our tools. Java is many times more powerful than Ruby, but that does not mean Java is the right tool for all problems. People that say ruby is the new java are misinformed. However one can not discredit ruby/rails, or dynamic languages in general, because it can not do everything java can. Its simply a different tool that takes a different (sometimes better, sometimes worse) approach to a problem. This is one of the reasons why I like JRuby. It blurs the lines between java and ruby.

The guys at Revolution Health are building their online portal with rails. I may not be that bold, but after browsing through their site and blog, I'd say they have been able to to some very advanced stuff with rails.

12:46 PM  
Blogger Bob said...

I don't doubt that you can build complex stuff with Ruby. It is a Turing Complete language after all. I just wouldn't want to maintain it.

1:02 PM  
Blogger Dustin said...

bwtaylor:

When type errors are the only kinds you have, this argument makes sense. Java's type system is poor compared to others out there.

I'll completely agree that you should be doing unit tests anyway. I write unit tests for my java code. I consider it an important part of the development cycle and it finds lots of bugs even when there is static typing.

In practice, I've had so many mystery problems with hibernate that I would gladly welcome something that only required me to look at the DB now and then.

Annotations in hibernate are just a late-bound scripting language running inside of an interpreter for which test cases require things like data and databases and a J2EE container.

Yes, I know, many people use hibernate successfully in many apps, but we've never ran into a problem where a google search has shown us to be alone.

People I know who actually use both hibernate and ActiveRecord have generally good things to say about the latter. I've only got experience with hibernate, so I just don't have good things to say about ORM. :)

1:18 PM  
Blogger Sony Mathew said...

Mystery problems with Hibernate - yes I totally agree. This layer is not as abstract is i'd like it to be.

11:19 AM  
Blogger Unknown said...

"Couldn't have said it better myself."

and promptly got hammered by Obie Fernandez:
http://www.jroller.com/obie/entry/top_10_reasons_why_java

8:01 AM  
Blogger Bob said...

Hammered? Ignoring Obie's strange obsession w/ sucking ass, every one of those arguments is a fallacy. He's just another half decent (but not great) programmer who's mesmerized by DHH and who doesn't think deeply enough about programming yet to understand whether his code is actually maintainable or not. Kind of funny though.

10:04 AM  
Blogger Ed said...

@bob: Obie sounds like the kind of guy that would be Bileblogged (and deserving of same) if he was a java developer. It's funny how some think that a stream of f-bombs substitutes for "intelligent discord" in a public forum.
-ed

1:43 PM  
Blogger Unknown said...

"I've written a fair amount of Python that auto-generates properties and converts invoked methods to internal dictionary lookups. Similar to a dynamic proxy in Java, just without the interface to bind to.

To my knowledge, there is no programmatic way of providing static information about classes that are dynamically enhanced in this fashion."


There are arguments con dynamic typing. This isn't one of them.

Try maintaining under Zope with ipython, or Django's manage.py shell. I'd *really* like someone to explain to me how these approaches are better/worse than having Java doc or Alt-F7/CTRL-ALT-B in IDEA in the Java system you have to maintain. Something that isn't based on taste.

I've maintained both styles and am not sold on the idea that dynamic v static type systems are an important decision point for code maintenance. The Java guys spend half their time hacking in dynamism. Big Python systems end up introducing extra typing around interfaces.

Maybe if you had Haskell's or OCaml's type system, it would matter under maintenance. Otherwise it seems that the right typing style "depends" and in a big enough system you'll want both kinds. Big enough being smaller than people in either camp seem to be willing to admit.

4:55 PM  
Blogger Stephan.Schmidt said...

@Bob:

Obie is one of those Ruby developers with no programming experience or no experience in maintaining software. Their opinion is worth nothing.

Often those people only do project and consulting work and move on after they finished their work.

So they never see the nightmares they've created and left for others to fix.

Beside that, most of the 10 points are just stupid.

Peace
-stephan

--
Stephan Schmidt :: stephan@reposita.org
Reposita Open Source - Monitor your software development
http://www.reposita.org
Blog at http://stephan.reposita.org - No signal. No noise.

10:55 PM  
Blogger Obie said...

Frankly, I'm annoyed at the holier than thou reaction over my blog post.

@Stephan: I have over 10 years of full-lifecycle professional programming experience, only half of which has been for consulting companies like ThoughtWorks. Plenty of people that know me in person can attest to my experience in that regard. I'll hold back the strong temptation to call you a fucking idiot for saying otherwise.

@Ed: I've actually been bileblogged more than once, thank you very much. In case you missed the memo, my Top 10 was humor and not intended to be considered as intelligent discourse.

@Bob: You don't know me or my code. Calling me a half-decent programmer is just crap.

1:47 PM  
Blogger Bob said...

@Obie: The irony in your statement is mind boggling. :)

You don't know what you don't know.

2:37 PM  
Blogger sandofsky said...

Yellowpages.com had a 10 year old codebase. It was 100,000 lines of Java. It was a total mess.

This year it was rewritten in Rails. It took took five developers four months from first subversion commit to public beta. Now it's under 10,000 lines.

Those 10,000 lines are clearer than anything from the legacy site. We assign developers to unfamiliar code and they're up to speed in no time.

As for complexity, those four months included writing a service tier that uses our proprietary Ruby library for FAST.

As far as the pluralization conventions:
Class names are singular.
Table names are plural.

Done.

If you don't like it, use set_table_name in your class.

I don't know what capitalization rules you're referring to. If you mean that classes are capitalized, all classes in Ruby are capitalized.

You can learn the "ancient tomes" of Rails by buying the book "Agile Web Development with Rails." It's available as a PDF.

4:14 AM  
Blogger Unknown said...

@dehora: had this same argument with Andy Oliver until I realized my vocabulary mistakes. Its not really a dynamic vs. static typing debate, you're right in that the Java guys are always trying to hack in dynamicity, its a type-safety debate. This is why

I'm wondering if a stripped down Groovy implementation might be pretty interesting, Dynamic typesafe Java.

@Obie: You mean to tell me your top 10 reasons blog wasn't a satire? Man, I feel stupid...(not a new feeling).

5:08 AM  
Blogger jarober said...

And yet, refactoring was invented in a dynamic language (Smalltalk) - not in the extant static languages of the time (C++).

Java IDEs copied the idea from the Smalltalk Refactoring Browser. The fact that Ruby simply doesn't have tools is not a fault of dynamic languages, as much as you static language fans would like to pretend otherwise.

7:01 AM  
Blogger Bob said...

@jarober I'm sorry, but you don't know what you're talking about. Smalltalk "refactoring" wasn't anything like what we have with Java-based refactoring.

@sandofsky: That's useful information about your project, but I'm not sure what you're trying to say. Do you think the problem was with Java vs. Ruby, or do you think it's more likely you over-architected your application the first time through?

@bill Great point about Java developers hacking in dynamicity. Java EE people jump to dynamic solutions and throw type safety out the window far too easily. This is most prevalent in web frameworks.

In a framework where you deal with request parameters directly (like Struts, RoR, etc.), the incoming request parameters are the only place you can't have type safety, and yet most frameworks throw away safety going from their code to the view and in the view itself. We end up with the worst of both worlds: verbosity and no type safety. You have to type a bunch of type information that means nothing. It's no wonder web developers prefer RoR.

This isn't Java's fault though. Now that we have such excellent tool support (generics, refactoring, etc.), Java programmers need to rethink how they design frameworks and start taking type safety into consideration. That's why I like GWT--for the first time, we have end to end type safety and you really don't have to think in terms of HTTP requests and responses. You can't say that about RoR. That's also why I wrote Guice.

8:12 AM  
Blogger jarober said...

@Bob - I think you haven't looked at Smalltalk if you have the idea that Java refactoring is significantly different.

But hey - thanks for the denial and obfuscation.

8:40 AM  
Blogger Unknown said...

There is another point: having your domain model depending on ActiveRecord ties it to a particular persitence mechanism. If you want to create a rich domain model that could be reused across applications, that could be a big problem.

8:48 AM  
Blogger Bob said...

@jarober: Are you claiming that you can even do something as simple as definitively renaming a method in a language without static typing? I'm sorry, but replacing the old method with code to automatically rename callers at runtime doesn't count.

BTW, if you like Smalltalk, I think Gilad Bracha has picked up where Strongtalk (Smalltalk w/ static typing) left off.

8:53 AM  
Blogger sandofsky said...

It was not overengineering. Ironically, it was the sprawl of unmaintained Java.

3:28 PM  
Blogger Slava Pestov said...

bob, if you like type safety why do you use Java, which is not type-safe?

1:58 AM  
Blogger Rakesh said...

@Brian:
As a semi-recent Revolution escapee, one thing you should know about that rails deployment is that as a single Rails application, that site rapidly became a nightmare to develop and maintain. I developed some of that UI stuff early on, over a year ago, and watched the archtectural shift from Rails backed by web services (most of them written in Java) to a RoR monolith. Performance, stability, and development pace all took a tremendous hit.

For more info, look around at the http://valleywag.com/tech/lazy-valleywag/steve-cases-revolution-health-looking-sickly-284422.php.

3:49 PM  
Blogger Unknown said...

"That's why I like GWT--for the first time, we have end to end type safety and you really don't have to think in terms of HTTP requests and responses."

@bob: admit it, you want to be able leverage IDEA all day long ;)

Fwiw, abstracting away HTTP is one of the design features I like least about web frameworks, not just Java ones. Granted I write protocols like Atompub in my spare time, but it's not like I'm about to swap out the HTTP layer (even for mobiles) for something else. Typing HTTP things is fine to point, pretending HTTP isn't there gets you WS-*.

5:06 PM  
Blogger artsrc said...

I use Hibernate mostly via JPA. In my experience the database definition of entities is a lot more important than the programming language one. Relational technology is not problem free, quite the reverse, that is why you have to deal with it.

Having programmers maintain two independent, inconsistent versions of an entity, one in Java and one in the RDBMS, seems unfortunate.

On my current project there was a move to get rid of the RDBMS version of the world, but Oracle is a bigger business than Objectivity.

8:06 PM  
Blogger Stephan.Schmidt said...

@obie: "I'll hold back the strong temptation to call you a fucking idiot for saying otherwise."

Indirect speech to insult someone is usually used as a tactic by 5-year olds: "I'm not saying your a fucking idiot, but ..." Huh. Get manners.

Beside that, you just proved my point. Thanks.

Peace
-stephan

2:03 AM  
Blogger Jonathan said...

Having rules and standards in programming are good, having them interlaced with a language, probably better. I have seen terrible crap code in all sorts of languages and the problem is there are far too many developers who learn how to do a for loop learn the concept of objects and arrays then say HEY I know how to program! and that's it they don't take any time to learn the tools of the trade to make their (any everyone who has too look and work with their code) lives easier. Shame on you for not having the constitution to learn new things and please find a new profession so I don't have to deal with your crap. And in 3, 5, maybe 10 years you'll either have "grown" up to management away from where you can do any harm and brag to everyone how "awesome of an programmer you use to be" or you'll still be supporting/developing C# and java apps long after the market for those languages have crashed miserably

8:04 AM  
Blogger Matt McKnight said...

Wow this makes Bob and (especially)Gavin look desparate. Everyone that's actually trying to use the technology instead of slamming it without thinking is using "annotate models", a plugin written by some bloke named Dave Thomas in an hour or so. It puts a comment in each of the model files with all of the information you need- including the exact information about what that field looks like in the database.

I love Guice; I just can't give you a free pass to dismiss the competition so thoughtlessly, it makes your own arguments much less compelling for people that can see you don't have knowledge about what you are criticizing. If you had simply asked any one of your many friends who know Rails, they could have easily answered this for you.

7:31 AM  
Blogger Stephan.Schmidt said...

@matt:

Rails developers: No attributes in the code, all we need is the database ... well we have a plugin which everyone uses and which pastes the information in the model because the initial idea wasn't that good.

Ruby developers: No static typing needed, dynamic typing is all we need ... well we tend to comment the methods with the types, because noone knows what types the method takes after 2 weeks.

Peace
-stephan

7:44 AM  
Anonymous Anonymous said...

There are migration files where database attributes (and constraints) are defined. Smart IDEs can figure that out. It's the same with Hibernate: Look at XML definitions or the classes.

I use both ActiveRecord and Hibernate and ActiveRecord is better in all areas (and about a 100x times faster to develop with).

12:50 AM  
Blogger Stephan.Schmidt said...

"(and about a 100x times faster to develop with)."

Good to have numbers, I'm for fact base technology comparisons.

How did you measure the 100x increase for Active Record? You wrote a DB table and an AR class and it took you, I guess 5min to get it working. Then you wrote the same as a Hibernate class and it took you 500min (8h) to get the class working. I'm astonished about what took you 8h for a Hibernate class, but good to see numbers. Am I wrong and you have measured something different, as I would like to take this fact of a 100x factor to my blog.

Thanks
Stephan

12:33 AM  

Post a Comment

<< Home