CActiveRecordMetaData interface


In my active record implementation the backing table may not exist when the record is created. If the CActiveRecord.getMetaData() returned a IActiveRecordMetaData instance I can swing it by implementing my own. (Currently I can fake it by returning a class which does the same as the CActiveRecordMetaData)

I think this could be useful in some applications. Possible ?



Explain a bit more why your scenario would happen in practice?

Since CActiveRecordMetaData is mainly for internal use, exposing it as an interface may not be good as it contains many public properties which can't be declared via interface.

My goal is pretty simple,

  1. A "setup module" function is called.

  2. This invokes an instance of my active record and calls the setup() function on it.

  3. The setup function calls the getFields() which returns a map of the fields and some meta data about the field types.

  4. The setup function then creates the table based on the information returned by getFields().

Right now step 2 fails …

What about adding createMetaData method to CActiveRecord so that you can override to create your own version of metadata object? You can then either extend CActiveRecordMetaData or write one from scratch.

There is already is a getMetaData method available which is easy enough to override. The issue lies with CActiveRecordMetaData, I cannot override its constructor. If the check for the existence of the table was moved to a protected method like init(), then I could override that call with my own implementation.

Why can't you override the constructor? I can't see the difference by moving the code from constructor to init… Maybe you need to access the private member $_model?

Yes by overriding the constructor it makes overriding all the other methods necessary - so it is almost like an interface :D

Hmm CActiveRecord is a bit different from Prados' active record so there may be an alternative way to approach this for me.

Thanks for the help I will let you know if there is an alternate approach to my issue.

My final approach was to use two classes, one extendable (my new "BActiveRecord"), the second a final class extending CActiveRecord. In the second class the getMetaData function was overridden to provide my own map of meta data objects. I can then create a new instance of the "BActiveRecord" without having the table in place.

This works well enough although I still think it would be useful to be able to define the table structure without having to goto the database table to fetch the column names for two reasons: 1) Performance - an array can be read from a lot quicker then a table schema, 2) Flexibility - Maybe you do not want to populate or retrieve all the fields from the table or the table does not exist yet.


I will keep this in mind. At this moment, let's keep the current design as we may change CActiveRecordMetaData. Wei and I are working on a scheme that would integrate SQLMap and AR, which would essentially solve the point 2. While for point 1, since the DB schema supports caching, so reading the schema data is shouldn't pose too much performance impact.