We have moved our forum to GitHub Discussions. For questions about Phalcon v3/v4/v5 you can visit here and for Phalcon v6 here.

Strange behavior saving at db

i have the following code


    public function setNewDefaultImgByHash($parameters){
        $itemImgDefaultOld=ItemImg::findFirst(
            array("item_id =  ?1 and default =  ?2",
                "bind"=>array(1=>$this->id,2=>1)));
        if($itemImgDefaultOld){
            $itemImgDefaultOld->default=0;
            $itemImgDefaultOld->save();
        }
        $itemImgDefaultNew=ItemImg::findFirst(
            array("item_id =  ?1 and hash =  ?2",
                "bind"=>array(1=>$this->id,2=>$parameter)));
        if($itemImgDefaultNew){
            $itemImgDefaultNew->default=1;
            $itemImgDefaultNew->save();
        }
        return;
    }

What im trying to do is get the old default set it to 0 then get the new img by a hash and set it as the new default. Checking the general query log from mysql it does the following


          430 Query SELECT `item_img`.`item_id`, `item_img`.`hash`, `item_img`.`img_type`, `item_img`.`route`, `item_img`.`default` FROM `item_img` WHERE `item_img`.`item_id` = '3' AND `item_img`.`default` = 1 LIMIT 1
          430 Query UPDATE `item_img` SET `img_type` = 'image/jpeg', `route` = './img/item/309e970fce75e4666b29113c6a57b967b', `default` = 0 WHERE `item_id` = '3' AND `hash` = '318919a3792c13a518987f07ceff1536d'
          430 Query SELECT `item_img`.`item_id`, `item_img`.`hash`, `item_img`.`img_type`, `item_img`.`route`, `item_img`.`default` FROM `item_img` WHERE `item_img`.`item_id` = '3' AND `item_img`.`hash` = NULL LIMIT 1

the first select is ok but the update is all wrong and the following select is also wrong. Ive ben trying for hours to get it to work but no luck so far.



33.8k

1) I think Phalcon updates all the fields of the model instance when calling the method. BTW, when updating you will use update(), not save().

2) Yeah, the hash = NULL it's logic 'cause you're passing $parameters, not $parameter.

1) I think Phalcon updates all the fields of the model instance when calling the method. BTW, when updating you will use update(), not save().

2) Yeah, the hash = NULL it's logic 'cause you're passing $parameters, not $parameter.

thank you for the reply, i changed the saves for updates and yeah the parameters was a typo

now this is what the sql is throwing


          446 Query SELECT `item_img`.`item_id`, `item_img`.`hash`, `item_img`.`img_type`, `item_img`.`route`, `item_img`.`default` FROM `item_img` WHERE `item_img`.`item_id` = '3' AND `item_img`.`default` = 1 LIMIT 1
          446 Query UPDATE `item_img` SET `img_type` = 'image/jpeg', `route` = './img/item/309e970fce75e4666b29113c6a57b967b', `default` = 0 WHERE `item_id` = '3' AND `hash` = '318919a3792c13a518987f07ceff1536d'
          446 Query SELECT `item_img`.`item_id`, `item_img`.`hash`, `item_img`.`img_type`, `item_img`.`route`, `item_img`.`default` FROM `item_img` WHERE `item_img`.`item_id` = '3' AND `item_img`.`hash` = '318919a3792c13a518987f07ceff1536d' LIMIT 1
          446 Query UPDATE `item_img` SET `img_type` = 'image/jpeg', `route` = './img/item/309e970fce75e4666b29113c6a57b967b', `default` = 1 WHERE `item_id` = '3' AND `hash` = '318919a3792c13a518987f07ceff1536d'

both updates are wrong, i just wanted to update their default column

the first update is changing the route of the new defaultimg when it was supposed to update default=0 to the old default

and the second update is assigning default to 1 which was correct but its changing the route as well. Now both imgs routes point to the same img which is the old default img route



33.8k

Well, they have the same routes because they are the same record. In the second SELECT you're searching a record that has a hash that is equal of the previous UPDATE record. So, you only change its default field, nothing more.

At least, that's what I see.

Well, they have the same routes because they are the same record. In the second SELECT you're searching a record that has a hash that is equal of the previous UPDATE record. So, you only change its default field, nothing more.

At least, that's what I see.

well i just did as follow to check what records i was getting


    public function setNewDefaultImgByHash($parameter){
        $itemImgDefaultOld=ItemImg::findFirst(
            array("item_id =  ?1 and default =  ?2",
                "bind"=>array(1=>$this->id,2=>1)));
        if($itemImgDefaultOld){
            $itemImgDefaultOld->default=0;
            var_dump($itemImgDefaultOld);
           // $itemImgDefaultOld->update();
        }
        var_dump("separator");
        $itemImgDefaultNew=ItemImg::findFirst(
            array("item_id =  ?1 and hash =  ?2",
                "bind"=>array(1=>$this->id,2=>$parameter)));
        if($itemImgDefaultNew){
            var_dump($itemImgDefaultNew);
            $itemImgDefaultNew->default=1;
            //$itemImgDefaultNew->update();
        }
        return;
    }

the only thing i did was comment both updates and add a few var dumps. This is what i got:

first search


  ["item_id"]=>
  string(1) "3"
  ["hash"]=>
  string(33) "309e970fce75e4666b29113c6a57b967b"
  ["img_type"]=>
  string(10) "image/jpeg"
  ["route"]=>
  string(44) "./img/item/309e970fce75e4666b29113c6a57b967b"
  ["default"]=>
  int(0)

second search


  ["item_id"]=>
  string(1) "3"
  ["hash"]=>
  string(33) "318919a3792c13a518987f07ceff1536d"
  ["img_type"]=>
  string(10) "image/jpeg"
  ["route"]=>
  string(44) "./img/item/318919a3792c13a518987f07ceff1536d"
  ["default"]=>
  string(1) "0"

both record have different hash and routes. how should i search for them if im doing it wrong. I'm losing hope :'c



33.8k

You could seach for them with item_id; they have the same one.



1.5k

You can change the behaviour of the update so it only includes changed fields in the UPDATE. By doing $this->useDynamicUpdate(true); in the initialize of your model see https://docs.phalcon.io/en/latest/reference/models.html#dynamic-update