[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