[Solar-talk] Changes afoot: a new Model class
Paul M Jones
pmjones at ciaweb.net
Wed Feb 7 16:58:27 PST 2007
On Feb 7, 2007, at 6:28 PM, Andreas Ravnestad wrote:
> Yes, I see clearly how it will work now. I couldn't see a save()
> method
> in Solar_Sql_Model_Record (I guess you haven't got that far yet), and
> that confused me :)
Yeah, not that far yet. :-(
> Still, I'm not sure where the business logic goes. I'm assuming it
> should be put in a subclass of Solar_Sql_Model, but then it's (very
> strictly speaking, unless using a technique like the one I showed
> in my
> previous email) unavailable in the records themselves (effectively
> removing alot of the "active" in "active record").
I think we have different needs on "business logic" and that's
coloring my approach. Very glad you brought this up. See further
down, for more.
> So should the business logic go into a subclass of
> Solar_Sql_Model_Record? That makes sense, but then I'd have to modify
> _recordset_class in my subclass of Solar_Sql_Model, as well as
> creating
> a subclass of Solar_Sql_Model_Record to implement my business logic
> in.
> Oh and that also means two subclasses per model. Yikes. Wait, maybe
> not
> necessary to subclass Solar_Sql_Model though. Hmm.
Well, you might need to subclass Model_Record, but I don't think
RecordSet would need subclassing. When you retrieve a Record from a
Model, it looks for that Model's Record, then moves up the class
stack until it finds a Record class, ending at
Solar_Sql_Model_Record. So if you had Model_Images_Record, it would
use that. The RecordSet class is smart enough to know what Record
class it should return for each record in the set, so even if you
have mixed Record types, you should get the right one each time. (Am
I missing anything here?)
> Anyway, by business logic I do not only mean things like filtering and
> validation (which you seem to have taken care of), but also
> anything you
> can think of to put in a domain model. For example, for an image
> model,
> it would be very plausible to add a method to generate and save
> thumbnail previews. I guess my question is this: where will this
> method
> go? The subclass of Solar_Sql_Model, or the subclass of
> Solar_Sql_Model_Record (if any)?
It could go as part of the insert/update mechanism in the master
Model, but I might be wrong there. More discussion below.
> Or, for a User model, it would be very plausible to add logic for
> complex authorization arithmetic. Or possibly unlink() a File model
> from
> the file system. And so on, I'm sure you see what I mean :)
I do indeed.
It seems to me, perhaps incorrectly, that these would be handled in
the "master" Model class, not in the record or recordset class. I
could be wrong, though, and am happy to hear other cases.
Let's take the "generate a thumbnail" example. You could do that on
save() in the Model, automatically (note that save() calls insert/
update depending on the presence of a primary key value in the data) ...
class Vendor_Model_Images extends Solar_Sql_Model {
public function insert($data)
{
$result = parent::insert($data);
// create the thumbnail image based on new data
$this->_createThumbnail($result);
}
public function update($data, $where)
{
$result = parent::update($data);
// update the thumbnail image based on new data
$this->_updateThumbnail($result);
}
protected function _createThumbnail($data)
{
// ...
}
protected function _updateThumbnail($data)
{
// ...
}
}
... or, if you wanted to do it by hand on each record, *then* you
would put it in the record, since you need it directly on each record.
class Vendor_Model_Images_Record extends Solar_Sql_Model_Record {
public function createThumbnail()
{
// uses $this->_data
}
public function updateThumbnail()
{
// uses $this->_data
}
}
Then on each record you have access to $image->createThumbnail().
If you *really* wanted to get tricky, you could add __call() to the
record class, and have it call methods in $this->_model as needed,
based on a whitelist of allowed methods or something. You could even
do that in a base Vendor_Sql_Model/Record/RecordSet class set, and
extend from that.
So I guess my answer is, "it depends". If the methods are needed
manually, per-record, or they only apply at certain times in the life
of each record individually, then in the Record seems best. But if
they apply for every record every time at existing hooks in the
Model, then in the Model seems best.
Does that help at all? If not, happy to talk more. :-)
--
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