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

How to use Model::skipAttributes()? I failed to work it out.

Hi, I got a problem about models.

DBAs in our company do not allow NULL fields for MySQL. So I have to set NOT NULL for every field. Indeed, you can give it a default value, and skip it when inserting/updating. But things are complicated, there are always empty values for them.

And we know phalcon has a district validation for models. So What can I do?

I found that phalcon\mvc\model has skipAttributes() method to solve this problem.

public function beforeValidation()                       
{                                                        
    $this->modtime = date("Y-m-d H:i:s");                

    $emptyAttr = array();                                
    $attrs = $this->toArray();                           
    foreach($attrs as $key => $attr) {                   
        if(empty($attr) && $key != 'addtime') {          
            $emptyAttr[] = $key;                         
        }                                                
    }                                                                               
    $this->skipAttributes($emptyAttr);                   
}                                                        

I tried it, And got a problem.

I want to parse XMLs and make them into MySQL. Bottom is the table schema. Field "assetnetvalue" in xml always has a non-empty value, but when I insert them in, the field "assetnetvalue" is empty for 2/3 of the records. So Why? It was skipped? No, I just var_dump the emptyArr for every record, and there is no "assetnetvalue". But the SQL told us it was skipped. See it below:

<ROW seqno="5257">                         
  <YHCODE>3878</YHCODE>                    
  <FUNDCODE>519886</FUNDCODE>              
  <PUBDATE>2013-12-31 0:00:00</PUBDATE>    
  <ASSETNETVALUE>8286773.69</ASSETNETVALUE>
  <SHARESCOPE>8286773.69</SHARESCOPE>      
</ROW>                                     
INSERT INTO `fnd_nav` (`yhcode`, `fundcode`, `pubdate`, `modtime`, `addtime`) VALUES ('3878', '519886', '2013-12-31 0:00:00', '2014-04-10 21:15:44', '2014-04-10 21:15:44')

So Why ???

CREATE TABLE `fnd_nav` (
 `id` bigint(10) NOT NULL AUTO_INCREMENT,
 `yhcode` varchar(10) NOT NULL DEFAULT '',
 `fundcode` varchar(6) NOT NULL DEFAULT '',
 `pubdate` varchar(31) NOT NULL DEFAULT '0000-00-00 00:00:00',
 `netvaluechg` decimal(20,18) NOT NULL DEFAULT '0.000000000000000000',
 `netvalue` decimal(10,5) NOT NULL DEFAULT '0.00000',
 `totalvalue` decimal(10,5) NOT NULL DEFAULT '0.00000',
 `totalvalueconvert` decimal(20,15) NOT NULL DEFAULT '0.000000000000000',
 `rwfnetvalue` decimal(10,4) NOT NULL DEFAULT '0.0000',
 `qrnhprofit` decimal(10,3) NOT NULL DEFAULT '0.000',
 `fundjztype` varchar(10) NOT NULL DEFAULT '',
 `assetnetvaluemain` decimal(20,2) NOT NULL DEFAULT '0.00',
 `sharescopemain` decimal(20,2) NOT NULL DEFAULT '0.00',
 `assetnetvalue` decimal(20,2) NOT NULL DEFAULT '0.00',
 `sharescope` decimal(20,2) NOT NULL DEFAULT '0.00',
 `h_rwfnetvalue` decimal(10,4) NOT NULL DEFAULT '0.0000',
 `h_qrnhprofit` decimal(10,3) NOT NULL DEFAULT '0.000',
 `h_fundjztype` varchar(10) NOT NULL DEFAULT '',
 `modtime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 `addtime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
 PRIMARY KEY (`id`),
 UNIQUE KEY `yhcode` (`yhcode`,`fundcode`,`pubdate`)
) ENGINE=InnoDB AUTO_INCREMENT=5329 DEFAULT CHARSET=utf8


9.4k
Accepted
answer

Solved.

skipAttributes() will merge the emptyAttr for each called. So at last, I would have skipped a large list of fields. Fortunately, it has a second parameter to let you replace the list for each time. But it is not well documented.

So I changed that to:

$this->skipAttributes($emptyAttr, true);

Everythis is OK now.

Thank u anyway.