Support the ability to write properties within models

My observation is that responsibility for the persistence layer may lie entirely outside the scope of projects that use an ORM of any description. Making the ORM responsible for defining the persistence layer in this case is worse than useless; it is dangerous.

Many projects leave database issues entirely in the hands of specialists who have their own tools to design and implement data structures. The current design of RoR handles this situation since it presents migrations/DDL as a standalone and dispensable feature. Used when needed and ignored when not.

I believe this is as it should be. Creating a database structure has nothing at all to do with programming access to it. Likewise, programming access to a persistence layer is simply dependent upon what already exists. Coupling these two separate functions will not be a happy marriage to my mind.

If you wish to be able to query a model to find out exactly what attributes it considers as relevant would it not be best to simply adopt a convention and provide a well known method name to return a string of attributes? Then designers can add that method and populate its return value in their models or not as they see fit. If the convention is followed then I believe you will obtain what you desire without affecting anything else. If the convention is not followed then that pretty much makes the argument that any other approach to provide the same information will not be valued as well.

This is a good argument. The generator was to me a way to prove the benefits of having properties declared within models, i believed it was generally agreeable as a point of strength but obviously it is not. It also leverage on the coupling (even if weak) between ORM and persistence while I'm trying to argue to the contrary: i wish to see in ruby on rails a level of abstraction between database columns and model properties in a way that client code (eg Paperclip) can interact with different ORMs in the same way.

What is your opinion about that?

Regards Maurizio

I'm one of the maintainers of the hobofields gem Andrew Mutz mentioned earlier, so I figured I'd toss my observations in.

To me, an in-model DSL provides two major benefits:

- enhanced readability of the class, both for the developer and for other code. For instance, compare these two models (loosely extracted from an old Rails 2.3 app of mine):

class CertificationPayment < ActiveRecord::Base

  validates_numericality_of :year, :only_integer => true, :greater_than => 2000

  belongs_to :detail, :class_name => 'CertificationDetail'    end

VS

class CertificationPayment < ActiveRecord::Base

  fields do     year :integer     contact_number :phone_number     payment_method :payment_method     check_number :string     amount :decimal, :scale => 2, :precision => 10     timestamps   end

  validates_numericality_of :year, :only_integer => true, :greater_than => 2000

  belongs_to :detail, :class_name => 'CertificationDetail'    end

I believe most developers would regard the second form as more understandable, especially if they were new to the codebase.

In the case of hobofields, there was the additional need to have more-specific type information for use by code that essentially generates forms on-the-fly at application load time. This arguably makes it *more* database-agnostic, since code that reflects on field types isn't tied to ActiveRecord::Base.columns.

- The second motivation was to provide a richer type system for fields than would otherwise be available. For instance, two of the fields in the example above use application-defined types (:phone_number and :payment_method). Underneath the hood, both fields eventually wind up as plain :string columns in the DB, but this interface allows the developer to be more specific in the description.

In addition, the rich types can provide additional validation, normalization, and formatting capability - :phone_number, for instance, normalizes whatever the field is set to to remove punctuation, validates that the resulting string is the correct number of digits, and formats the data back into US format for display. None of this is particularly amazing - but the truly handy thing with rich types is that it is modular - changing an application to store / format non-US phone numbers with this method would be a matter of redefining the type, not rewriting validations in many places. Validation objects can certainly streamline this in plain AR, but you still need to remember to use them every time you have a model that uses that type.

I believe most developers would regard the second form as more understandable, especially if they were new to the codebase.

Yes they will :wink:

In the case of hobofields, there was the additional need to have more-specific type information for use by code that essentially generates forms on-the-fly at application load time. This arguably makes it *more* database-agnostic, since code that reflects on field types isn't tied to ActiveRecord::Base.columns.

Sometimes it seems that RoR active record implementation is not an Object Relational Mapper but rather a one-way Relational->Object Mapper, in the sense that it maps database columns to object methods and not the contrary overexposing persistence to the external world. Model declared fields should be to columns what Classes are now to tables.

The fact that AR requires an encapsulation of the functionality of persistence in business objects does not mean that we must strengthen all kinds of coupling to the persistence layer. Separation of concerns is a good idea if we can have it without make things too complex.

Maurizio