codeigniter4 / CodeIgniter4

Open Source PHP Framework (originally from EllisLab)
https://codeigniter.com/
MIT License
5.35k stars 1.9k forks source link

find() is returning one character string instead of boolean #2096

Closed hlohrenz closed 5 years ago

hlohrenz commented 5 years ago

Describe the bug I have a postgres database and after I insert a record using CI's query builder, I see that the boolean field can_be_sold is indeed inserting as a boolean. However after I perform a find() on this record, it's returning a string as "t" instead of true. My ItemModel looks like this:

<?php namespace Item\Models;

use App\Models\BaseModel as Model;

class Item extends Model
{
    protected $table      = 'items';
    protected $primaryKey = 'id';
    protected $returnType = '\Item\Models\Item';

    protected $allowedFields = ['name', 'description', 'image_path', 'can_be_sold', 'rarity'];

    protected $useSoftDeletes = true;
    protected $useTimestamps  = true;
    protected $skipValidation = true;
}

My BaseModel looks like this:

<?php namespace App\Models;

use CodeIgniter\Model;

class BaseModel extends Model implements \JsonSerializable
{
    /**
     * Fields to hide when being serialized.
     *
     * @var array
     */
    protected $hidden = [];

    /**
     * Populate model with array of data.
     *
     * @param array $data
     * @return Model
     */
    public function populateFromArray(array $data)
    {
        $classSet = \Closure::bind(function ($key, $value) {
            $this->$key = $value;
        }, $this, get_class($this));
        foreach (array_keys($data) as $key)
        {
            $classSet($key, $data[$key]);
        }
        return $this;
    }

    public function toArray()
    {
        return (array) $this;
    }

    /**
     * How object returns when being serialized.
     *
     * @return array|mixed
     */
    public function jsonSerialize()
    {
        foreach ($this->hidden as $field)
        {
            unset($this->$field);
        }

        return $this;
    }
}

CodeIgniter 4 version "codeigniter4/framework": "4.0.0-beta.2"

Affected module(s) CodeIgniter\Model

Expected behavior, and steps to reproduce if appropriate It should return boolean as it is pulled from the database. I am looking at the record and it is boolean datatype and is states true.

Context

hlohrenz commented 5 years ago

Unfortunately, it seems to be a postgre issue after digging into the CI code and doing multiple var_dump's everywhere. Would it be bad if I set some sort of mutator on the class to convert it to a boolean? This is unfortunate that postgres returns it as a string... seems strange to have that kind of behavior. Or maybe I should go with a different database driver altogether?

nowackipawel commented 5 years ago

First: pls check on current CI version. Second : paste entity code .

On Fri, Jul 19, 2019, 22:45 hlohrenz notifications@github.com wrote:

Unfortunately, it seems to be a postgre issue after digging into the CI code and doing multiple var_dump's everywhere. Would it be bad if I set some sort of mutator on the class to convert it to a boolean? This is unfortunate that postgres returns it as a string... seems strange to have that kind of behavior. Or maybe I should go with a different database driver altogether?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/codeigniter4/CodeIgniter4/issues/2096?email_source=notifications&email_token=ACAGMUQSCBOUZVOCL232ZYDQAHOSLA5CNFSM4IE6SGYKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD2MAE7A#issuecomment-513278588, or mute the thread https://github.com/notifications/unsubscribe-auth/ACAGMUVCUGR5GHTM5FIX4LDQAHOSLANCNFSM4IE6SGYA .

MGatner commented 5 years ago

@hlohrenz How did you end up handling this? If Postgres is returning boolean datatypes as "true" and "false" it seems to me that is something that should be converted in the driver to actual PHP `bools.

pjsde commented 5 years ago

Since this is a problem with Postgres, it should not be handled by the driver but by Entity class because in the end what is happening is that the returned value is not a bool but text.

If handled by the driver it will create extra processing and may lead to performance issues in large tables.

I think it should be the Entity to cast these fields as it is done for MySql users.

jim-parry commented 5 years ago

On investigation, this appears to be "normal" postgres behavior, and the recommended approach to get around t is to cast or convert the result yourself. I don't think this should be treated as a fixable bug, and will close the issue.