1

I am looking for a way to improve a model I have created.

What I am doing is using the model to create new pricing information on the fly, and set this information along with expiry times. The approach I am using is to offload some of the timing operations to the Database server using a Zend_Db_Expr to achieve this.

The problem I have is that after doing this I need to further make use of the model itself for further purposes. This means I need to get the actual result of the Expression inserting in to the database.

I have removed some of the code from this example as its business logic and should not impact on the question or answer anyway.

class My_Module_Model_Price extends Mage_Core_Model_Abstract {
public function getPrice() 
{
      $this->addData(
            array(
                'current_price'     => $this->getSpecialPrice(),
                'product_id'        => $this->_product->getId(),
                'price_from'        => new Zend_Db_Expr('NOW()'),
                'price_to'          => new Zend_Db_Expr('DATE_ADD(NOW(), INTERVAL ' . $endTime . " MINUTE)"),
            )
        );
$this->save();
}
    public function _afterSave()
    {
        if ($this->getData('price_from') instanceof Zend_Db_Expr) {
            $this->load($this->getData('id'));
        }
    } 

This logic gives me what I require, i.e. after calling it I am able to use $model->getData() and this returns the fields generate db the DB Expressions but I feel like I am doing an extra DB Query round for no useful reason just to get back some information. So my goal would be to convert the _afterSave such that I dont need it at all, or that I dont need to trigger a load within the model.

  • If I clearly understand you, you need smth like set on the fly price for a period of time (for example: you have 14 hours to purchase this product with special price $9.99)? And for some purposes you need your object to contain this (or some another) data for further purposes? That because you are looking for a way how and where to contain it? – zhartaunik Apr 17 '15 at 14:06
  • Hi @zhartaunik Yes, the special price can be generated in two different ways, the primary way is on cron automatically, so it will check if it already exists and do a normal load so the expiry information will be already in plain text format in those situations. Its only when it finds it hasnt got a valid one that it needs to regenerate and update - in which case the save leaves the data in the Zend_Db_Expr format which beyond that we need primarily for the front the calculated values - hence the _afterSave. But it feels like an excessive step and bad practice. – John Cuthbert Apr 17 '15 at 14:09
  • I'm sorry its hard to understand everything. As I understand if (price exists) { load } else { generate it }. Generation step should contains some Zend_Db_Expr but at this moment you don't have this value. And you will have it during save and afterSave? Could you please show us the sequence of load/save/apply/appearing value for Zend_Db_Expr/etc... – zhartaunik Apr 17 '15 at 14:22
  • The sequence is essentially that. ($this->save()) creates a record at which point doing $this->getData('price_to') is an instance of Zend_Db_Expr not a string of the generated result. ie before $this->save() $this->getId() doesnt have anything, after save the record exists, so we re-load the model just the same as if we done $model->load(1) this pulls the relevent actual field values from the Database ie select * from tbl where id =1 – John Cuthbert Apr 17 '15 at 14:23
1

I think there is no problem and you do not need to load the $model again.

Sequence is following:

_beforeSave()

save() //model in not saved!!!

_afterSAve() //model is still not saved!!!

on afterSave dispatching some events such as 
    Mage::dispatchEvent('model_save_after', array('object'=>$this));
    Mage::dispatchEvent($this->_eventPrefix.'_save_after', $this->_getEventData());

commit() And only now magento save changes to database 

So you evend don't need to use method _afterSave() you can use one of events with following check:

if ($observer->getObject instanceof My_Module_Model_Price) {

upd.1 You have some non logical things. For example you named method getPrice(). In this method you need to receive smth. In your case better use name: applyPriceRanges(). And code for this method is following:

$this->setData('current_price', $this->getSpecialPrice())->setData( /* .... */ )->save()

and in _afterSave() method or in observer try to do your changes with your object.

|improve this answer|||||
  • Not sure that the Observer could help in the scenario $info = Mage::getModel('model')->getPrice(id); $info->getData('price_to') ; // instance of Zend_Db_Expr not string. Even passing the object into an observer without the afterSave would maintain the object type If I am not mistaken? – John Cuthbert Apr 17 '15 at 15:20
  • added upd.1 section – zhartaunik Apr 17 '15 at 20:17
  • Surely setData vs addData doesnt change anything I still would need to convert or reload in _afterSave to make the Zend_Db_Expr a string. The $this->load($this->getData('id')); line is what I'm trying to avoid needing to do. – John Cuthbert Apr 18 '15 at 10:44
  • Ok, I agree with your point. But I have another question: why do you use Zend_Db_Expr to get current time? Why don't you use php or even Zend functions? – zhartaunik Apr 18 '15 at 11:42
  • That is a valid point to consider, I may end up going that way if there is no practical option. My primary reason for it has been to off load date operations to the server since a lot of queries will be ran on the server it'll ensure that its always in the correct format with no risk of errors introduced from parsing over from php to mysql. – John Cuthbert Apr 18 '15 at 11:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.