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 tell why is create()/save() failing.

Hi all,

I have a model that is failing to save. When I call create() on the model, it returns false. Where do I go from here? What diagnostic tools are available for me to see why it's failing?

I can't seem to find any documentation on how to either A) get the raw SQL or B) somehow access an error message. I do know that calling $NameOfMyObject->getMessages() gives me nothing.



19.2k

Hi @quasipickle You can use debug component https://docs.phalcon.io/en/latest/reference/debug.html#debug-component Also check that you have {{ content() }} in related view, it may be the answer why you don't see model validation messages

I don't have {{ content() }} but thanks for the heads-up.

I knew a little about the debug component - I was hoping there was a less arduous method of getting some feedback from save().

It looks like the debug component is just something that captures all thrown exceptions and displays them nicer. create()/save() isn't throwing an exception, it's returning false. I just don't know WHY it's returning false. Thanks for the suggestion though.



19.2k

Well, it should return false if model wasn't saved, but model also should return validation messages, check this article https://docs.phalcon.io/en/latest/reference/models.html#validation-messages and make sure you've set it up correctly. I think you just missing output of those messages. Try to add php <?php echo $this->getContent(); ?> (or php {{ content() }} if you are using Volt) to the related view, it should solve the problem.

I've pasted the model that is failing below. There is little validation to do. What is done is moving a file on the filesystem when the "beforeCreate" event is fired. The beforeCreate() function is run every time, so it looks like the model is getting past whatever built-in validation it needs to.

"File" model

<?PHP
<?PHP
namespace App;
use \Phalcon\Mvc\Model\Message;

class File extends \Phalcon\Mvc\Model{

    use \MessagesTrait;

    private $upload_dir = NULL;
    private $download_dir = NULL;

    /*
     * All of the following functions are built-in functions called 
     * automagically at various points by Phalcon
     */

    public function initialize(){
        $this->belongsTo('id','App\Request','request_id',
            [
                'foreignKey'=> [
                    'action'=>\Phalcon\Mvc\Model\Relation::ACTION_CASCADE
                ]
            ]
        );

        $DI                = \Phalcon\DI\FactoryDefault::getDefault();
        $Config            = $DI->getShared('config');
        $this->upload_dir   = $Config->app->upload_dir;
        $this->download_dir = $Config->app->download_dir;
        unset($DI,$Config);
    }

    # On create, moves the uploaded file from the upload to download directory
    public function beforeCreate(){
        $uploaded_path = $this->upload_dir.$this->filename;
        $destination_path = $this->download_dir.$this->request_id.'/'.$this->filename;

        if(!$this->_validateFilePath($uploaded_path))
            return FALSE;

        if(!$this->_moveFile($uploaded_path,$destination_path))
            return FALSE;

        return TRUE;
    }

    public function afterSave(){
        dump($this->connection);
        exit();
    }

    /*
     *
     * Helper functions called non-automatically
     *
     */

     private function _validateFilePath($path){
        if($path !== realpath($path)){
            $Message = new Message(
                'The requested file ('.$path.') is not a valid uploaded file.',
                'file'
            );
            $this->appendMessage($Message);
            return FALSE;
        }
        else
            return TRUE;
    }

    private function _moveFile($upload_path,$destination_path){
        if([email protected]($upload_path,$destination_path)){
            $this->appendMessage(new Message(
                    'Error while moving uploaded file to Request-specific directory.',
                    'file'
                )
            );
        }
    }   
}
?>

Here is the function in the relevant \App\Request model that initiates the saving of the File object.

<?PHP
public function associateFile($filename){
    $File                    = new \App\File();
    $File->request_id        = $this->id;
    $File->filename          = $filename;
    $File->type              = 'test';
    $File->filename_original = 'blah';

    if(!$this->setupFileDirectory())
        return FALSE;

    if(!$File->create()){
        // This always gets run, so $File->create() is returning false
        // $File->getMessages() never contains anything
        $this->appendMessages($File->getMessages());
        return FALSE;
    }

    return TRUE;
}

Um, ya.... so one of my validation functions wasn't returning TRUE, so my beforeCreate() function was returning FALSE. Guess you're never too experienced to avoid making dumb mistakes.

Thanks @chebureque for trying to help.