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

Exclude columns from findFirst()

Does Phalcon provide a way to remove database columns from findFirst() result so I don't send the column "id" in a JSON response?

If not, I would like to know how you would do it.



11.6k
         $client = Clients::findFirst(
                    array(
                        'conditions' => 'id = :cid:',
                        'bind' => array(
                            'cid' => $clientId
                        ),
                        'columns' => array(
                            'oneColumn',
                            'anotherColumns',
                            'andSoOn'
                        )
                    )
                );

I am trying to get the opposite, if possible. Because it's a table with many rows I'd have to specify all of them without only the id.



11.6k

I don't think what you want exists...pass your resultset in a foreach loop where you unset the unwanted properties...but what are takin care of? not passing the id for security reason? if it's to save bandwith, it's not a worth to let Id columns in your rep...

Hey @Miguel as @Graphmatic mentioned there is no such method available. Here is a simple way you can achieve this:

// This will give you array containing all the columns for the given model
$obj = new YourModel();
$tableColumns = $obj->getModelsMetaData()->getAttributes($obj);

// Sample output when printing $tableColumns
Array
(
    [0] => id
    [1] => is_active
    [2] => category_id
    [3] => created_at
)

// Unset columns which you want to excldue
$exclude = ['created_at', 'category_id'];
foreach ($exclude as $column) {
    $key = array_search($column, $tableColumns);
    unset($tableColumns[$key]);
}

// Sample output when printing $tableColumns after unset
Array
(
    [0] => id
    [1] => is_active
)

// And after all that you can pass to columns method only the columns you need
->columns($tableColumns)
edited Jul '16

Since findFirst() method returns object, the most effective solution would be to do

unset()

on properties you don't need in a result set. @nikolay-mihaylov (Nikolay Mihaylov) provided nice example.

Though I must agree that almost every ORM implementation has it's limitations, one being this simple task to filter out data prior to getting results back from data store.

@0x0a, thats also an option, but better not to select unneeded data in first place :)

@Dima, always specify which columns you want to fetch, after all performance is the main reason we use Phalcon!

edited Jul '16

Sure, but if it's just an id (single property), it should not impact runtime performance, quite the opposite - it's better to query database as: SELECT * FROM table WHERE Condition = something than: SELECT long, list, of, every, column, except, only, unneeded, one FROM table WHERE Condition = something

@stamster of course of course :)

My idea was to not select text or other big fields if you only need to display title and date. We are clear now ! :)

edited Dec '18

I'm building a RESTful API. I have a users table, and of course I don't want users' passwords and emails to be included in any API response. My approach is to create two models for the same table. One model would be User and another model would be PublicProfile. In the PublicProfile model I defined the metaData() method in a way similar to the example given here: https://docs.phalcon.io/el/3.3/db-models-metadata#strategies-manual I excluded the password and email fields from the meta data for the PublicProfile model. In this way, when a user requests other users' profiles I would use the PublicProfile model. When operations are being made on his own profile, I would use the User model and unset the password before responding to GET requests.