Open jerfowler opened 14 years ago
Thanks for this. Will consider it when we get a chance to look through properly.
At the very least, I think the benefits of using the serializable interface are too great to ignore. Have you seen the length of the returned string when serializing a model, such as an Auth User model when just using __sleep? Compare that to the length when using my serializable interface.
However, I have been giving the ArrayAccess and IteratorAggregate interfaces on the Model some thought. All I've really done is just create a shortcut to the as_array function... which really isn't that useful to be honest... However, I thought of a better use for those interfaces in the Model... It boils down to the fact that I really don't like that builder can return two different types of objects from its queries.. A Model or a Collection.
I propose a better solution where there should be a bidirectional link between the Collector object and the Model object so that one could iterate through and have array access to the Collection from within the Model. Also, rather than instantiating multiple clones of the same model while iterating through a collection, it should just reuse the existing model and just load_values() for the next row's set of values. Or better yet, store all data exclusively in the collector and have it keep track of changes. One could then do batch inserts/updates of a model using a single query. With a single save() it would iterate through the collection inserting new values or updating changes.
New models would have an empty Collection object and new rows could be added. I plan on throwing some PoC code together here soon, but I have a project near deadline so my attention is on that right now.
What are your thoughts?
At the very least, I think the benefits of using the serializable interface are too great to ignore
I'm sure they are, I've not looked into that interface in detail. When was it introduced?
However, I have been giving the ArrayAccess and IteratorAggregate interfaces on the Model some thought.
Indeed, I'm not convinced they offer anything valuable.
I propose a better solution where there should be a bidirectional link between the Collector object and the Model object so that one could iterate through and have array access to the Collection from within the Model
I don't follow this. Can you give an example of how this would be useful.
Also, rather than instantiating multiple clones of the same model while iterating through a collection, it should just reuse the existing model and just load_values() for the next row's set of values
I thought this is exactly what happened. If the code has changed, it was probably for a very good reason (unexpected results in certain situations perhaps).
Or better yet, store all data exclusively in the collector and have it keep track of changes.
This is a massive conceptual shift away from active record pattern. I'm not really sure it will integrate nicely or coherently with the rest of Jelly's API.
One could then do batch inserts/updates of a model using a single query
This should be achieved using the builder. Jelly is designed around the fundamental principle of being an object based extension to Kohana's Query builder, what you propose is a completely different way of modeling and working with data. Not that it is a bad idea just really not where we are heading with Jelly for now.
Perhaps I have misunderstood your points. If so please explain in a little more detail what you are proposing and what problem it solves.
I'm sure they are, I've not looked into that interface in detail. When was it introduced?
5.1, KO3 has a 5.2 requirement so we should be good.
I don't follow this. Can you give an example of how this would be useful.
Well, I haven't thought through all the details yet. I'm just kinda spit balling ideas here. I just thought that the builder should always return a model class whether it is just one or a collection of several. The model's values will always be set to the current() row when returned from the builder. One can than iterate through the collection by using the model's interface. Give me some time to fill in the gaps and give you a better use example.
I thought this is exactly what happened. If the code has changed, it was probably for a very good reason (unexpected results in certain situations perhaps).
In the collection, you can see below a new model is cloned every time _load is called. protected function _load($values, $object) { ... $model = clone $this->_model; ... }
This is probably done so that a model and its values can be assigned to a variable for later reference while iterating through the collection. Which I can totally understand that would be helpful, when one needs to do that, but I don't think that should be the default behavior. Perhaps a clone() method introduced to the Model class can be used in those situations.
This is a massive conceptual shift away from active record pattern. I'm not really sure it will integrate nicely or coherently with the rest of Jelly's API.
I don't think it will be that big of a shift. Again, let me flesh out this idea some more and I'll come back with some clearer examples and some sample code.
This should be achieved using the builder. Jelly is designed around the fundamental principle of being an object based extension to Kohana's Query builder, what you propose is a completely different way of modeling and working with data. Not that it is a bad idea just really not where we are heading with Jelly for now.
No, I still plan on utilizing Kohana's Query Builder, actually I plan on utilizing it more. Already in the Insert Builder there exists functionality of supplying multiple sets of values to a single insert query. As far as updates, I plan on utilizing the parametrization functionality that currently exists.
Perhaps I have misunderstood your points. If so please explain in a little more detail what you are proposing and what problem it solves.
Details are coming shortly, please stand by....
This is probably done so that a model and its values can be assigned to a variable for later reference while iterating through the collection.
This is exactly the reason it was changed. I can't remember which issue it was changed for, though.
The idea of a clone() method seems unintuitive. I'm still unclear as to why you think it's better to be passing around the same instance.
Isn't cloning quite a big performance hit compared to changing values, when iterating through a collection ? I think jeremyf76 is throwing some really nice ideas there. The idea of having a Model tied to a Collection would fix this annoying thing of Jelly returning either a Collection or a Model (see #97), and could indeed improve the iterating process. I am following the main concepts here, and think they could be really interesting, just curious to see some code !
@jonathangeiger The related issue is #87
I just posted this in #87... Probably should have done it here... Personally, I feel it should be the responsibility of the coder to clone his own models. Otherwise your just instantiating objects, duplicating array values, eating memory and wasting processor cycles every time you iterate through a collection.
Interfaces: Jelly_Collection_Core and Jelly_Model_Core, New: Serializable, new functionality which replaces __sleep. Serializable::Serialize, Stores the very minimum amount of data (model name, and array of values) to the serialized string rather than huge blob of useless data. Serializable::Unserialize, recreates the object from the serialized string
Example: $users = Jelly::factory('User') ->get_by_roles(array('admin'), array('or' => 'login'));
Jelly_Model_Core, New: IteratorAggregate, allows iterating through the model's values with a foreach loop.
ArrayAccess, gives the model array-like access to the field values
Example:
Magic functions: Jelly_Collection_Core: __toString, default conversion of an object to a string
Example output: Jelly_Collection: role (2)
This functionality is in my latest commit on my fork.