Missing the Point
Giorgio Sironi writes about (among other things)his first experience with Rails over at Web Builder Zone:
class Post < ActiveRecord::Base
Oh thanks, now I’m enlightened. No fields, no scope, no getters or setters. What is going on here? Where is the business logic?
It’s a common enough reaction from Rails newcomers, but it completely misses the point.
There are no fields, etc., shown because they are all supplied by Rails by default. You don’t need to write them, and their operation is so obvious you don’t need to see the code for them. There’s no business logic because as yet he hasn’t supplied any; any attempt by the system to automatically create some at this point is doomed to fail because of insufficient information.
You want to see the database fields you’ve created, check the schema.rb file—that’s where you’ll find them. You want your code to access them? Post.fieldname does that; set the value by assigning to it, get the value by reading from it.
To be sure, the context of the article is not supposed to be explaining either Ruby or Rails, but rather what the next generation of PHP frameworks have learned, either from Rails or from their own past. But when he extols the development in Doctrine 2 that allows you to override the default getters and setters with entries in a class file located in a special location in the hierarchy, he doesn’t appear to realize that the Ruby file he was just complaining about being empty performs that same exact function. (Instead, he implies that you can’t do it at all in ActiveRecord, which is patently untrue.)
To override the default getter for the field “date”, for example, you would create a method for date in the existing file (why you’d want to override the default getter for a database field, is another question). Or to create a new field based on it, let’s use “creation_year” for an extremely simple example, you would create a method entitled “creation_year” which would take the date created and pull out just the year. In like manner, to create a custom setter for a field such as, say, “permalink” (to keep with his blog example) you would create a method entitled “=permallink”—Ruby-ese for creating a setter— and inside that method place the business logic for creating a permalink.
I suspect the source of this error is he expected Ruby to work like PHP. It doesn’t, but often it takes a while for newcomers to the language to understand that. Ruby may bear a superficial resemblance to it on the surface, but trust me; it’s horse of a completely different color. It might even be a zebra.
Thanks for the information, I have started to explore Rails in more depth now:
My preference still goes to keeping field definitions and related business logic in the same Model class, like DataMapper for Ruby does.
My example on “overriding the default getter” was related to the lack of magic fields, which in PHP are implemented with the __get() method. The problem created by such features in PHP was that when a method is called or a field accessed, no one would know with certainty where the executed code would be.