[Solar-talk] The new model class discussion, some questions

Paul M Jones pmjones at ciaweb.net
Mon Feb 19 08:47:34 PST 2007


On Feb 19, 2007, at 9:51 AM, Rodrigo Moraes wrote:

> On 2/19/07, Paul M Jones wrote:
>>      // work with the Model as a whole
>>      $data = array('status' => 'public');
>>      $where = array('area_id = ?' => 1);
>>      $model->update($data, $where);
>>
>> That last one, "work with the Model as a whole", is a key feature; in
>> Solar, you should be able to access the Model (i.e., the table and
>> its relationships) directly if needed.
>
> But this would be possible to execute in any TableModule.

Correct, and if it were possible, I'd do so using static methods  
rather than instance methods.  But in PHP that becomes rather  
difficult without a lot of extra work.


> On the other hand, can you instantiate Solar_Sql_Model_Record, set  
> some values and
> save it? If not, then the record is not capable of starting its own  
> table and save itself. :-|

That's correct, you cannot do it that way under the current  
implementation.  Instead, you would instantiate the model and call  
fetchNew() from that model, like this:

     $model = Solar::factory('Solar_Model_Nodes_Wikis');
     $record = $model->fetchNew();
     $record->subj = "New Title";
     $record->save();

Is that not sufficient?  Happy to hear counter-arguments here.


> I commented in #solarphp at greenode.org: you can probably achieve the
> same you ever had with a Solar_Sql_Model_Record subclass, ut not with
> a subclass of your record; I'm still in doubt, but don't you think
> that a record is much more worth to subclass than a table?

I think a "model" is the thing to subclass, not records pertaining to  
that model, but I could be mistaken here.  Am very willing to revisit  
my decisions and convert to other techniques, if warranted.


> I mean:
> - You have a table schema in Model an your domain logic is in
> Model_Record; Solar will find Model_Record based on Model;
> - If you have a second use for a table schema, with different
> relationships etc, you'll need Model2 and Model2_Record;

Not necessarily Model2_Record.  If you have a second use for the  
table schema, that's what is called "single table inheritance": many  
different classes using the same table, with their own domain logic,  
including different filters and relationships.

We can see this with Solar_Model_Nodes right now:  you can have  
bookmarks, wiki pages, blog posts, and comment entries all in the  
same table; the "type" column indicates what model should be used for  
generating and saving records, and those different models can have  
their own relationships.  There's no need for separate record classes  
in such a case; they can call be handled by the Model domain logic,  
because each Record is tied back to its own Model.

Here's an example: we have the Areas table and the Nodes table, but  
the Nodes table is the source for a Wikis model *and* a Revisions model.

     class Solar_Model_Areas extends Solar_Sql_Model {
         protected function _setup()
         {
             parent::_setup();
             $this->_hasMany('nodes', array(
                 'fkcol' => 'parent_id',
             ));
         }
     }

     class Solar_Model_Nodes extends Solar_Sql_Model {
         protected function _setup()
         {
             parent::_setup();

             // turns on single-table inheritance
             $this->_special_cols['inherit'] = 'type';

             $this->_belongsTo('area', array(
                 'model' => 'areas',
                 'fkcol' => 'area_id',
                 'eager' => false,
             ));
         }
     }

     class Solar_Model_Nodes_Comments extends Solar_Model_Nodes {
         protected function _setup()
         {
             parent::_setup();
             $this->_belongsTo('node', array(
                 'model' => 'nodes',
                 'fkcol' => 'parent_id',
             ));
         }
     }

     class Solar_Model_Nodes_Wikis extends Solar_Sql_Model_Nodes {
         protected function _setup()
         {
             parent::_setup();

             $this->_hasMany('revisions', array(
                 'fkcol' => 'parent_id',
                 'order' => 'id DESC',
             ));

             $this->_hasMany('comments', array(
                 'fkcol' => 'parent_id',
             ));
         }
     }

     class Solar_Model_Nodes_Revisions extends Solar_Sql_Model_Nodes {
         protected function _setup()
         {
             parent::_setup();

             $this->_belongsTo('node', array(
                 'model' => 'nodes',
                 'fkcol' => 'parent_id',
                 'eager' => false,
             ));
         }
     }

All the Nodes inheritance-types (Wikis, Revisions) use the same table  
(nodes) and the same record class (Solar_Sql_Model_Record) even  
though they are attached to different models; this is because all the  
domain logic is at the model/table level, not the individual record  
level.

Note also that a comment belongs to any kind of node, but when you  
retrieve the parent-node of that comment, you automatically get back  
a record tied to the correct model for that parent-node.  This is  
single-table inheritance in action.

I hope that makes some sort of sense; please let me know if it does not.


> Or: how would one extend the record domain logic?

It depends on what you want to do; can you give an example of record- 
specific logic so we can examine the situation?  (Right now, domain  
logic sits at the table/model level, not at the record level.)  What  
would you want to do at the record level that you would not want to  
do at the table level?

Again, I am willing to revisit my design decisions so far and  
converting to a record-based (not table based) model system based on  
examples and discussion.  Solar_Sql_Model is not set in stone just  
yet.  :-)


--

Paul M. Jones  <http://paul-m-jones.com>

Solar: Simple Object Library and Application Repository
for PHP5.  <http://solarphp.com>

Join the Solar community wiki!  <http://solarphp.org>

Savant: The simple, elegant, and powerful solution for
templates in PHP.  <http://phpsavant.com>




More information about the solar-talk mailing list