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

Question about query Builder

Are the results of query different in single Model or in custom ?

For example in the single Model, the query builder is like this:

use Phalcon\Mvc\Model\Query\Builder;

$builder = new Builder();
$builder->addFrom(Contest::class, 't1');

foreach ($where as $field => $value) {
    $builder->andWhere(
        sprintf('%s = :%s:', $field, $field),
        [$field => $value]
    );
}

if (true !== empty($orderBy)) {
    $builder->orderBy($orderBy);
}

this code can work properly, and the Model is contest, see the picture below:

But if I use custom query:

use Phalcon\Mvc\Model\Query\Builder;

$builder = new Builder();
$builder
    ->columns(['contest_id' => 'cp.contest_id', 'problem_id' => 'cp.problem_id', 'num' => 'cp.num',
        'id' => 'c.id', 'title' => 'c.title',
        'pid' => 'p.id', 'ptitle' => 'p.title'
        ])
    ->from(['cp' => ContestProblem::class])
    ->innerJoin(
        Contest::class,
        'c.id = cp.contest_id',
        'c'
    )
    ->innerJoin(
        Problem::class,
        'p.id = cp.problem_id',
        'p'
    )
    ->where('cp.contest_id = :id:', ['id' => $id]);
$builder->orderBy('cp.num ASC');

It says it's not a Modle but a Row:

TypeError: Argument 1 passed to \Api\Transformers\BaseTransformer::transform() must be an instance of \Api\Mvc\Model\AbstractModel, instance of Phalcon\Mvc\Model\Row given, called in .../vendor/league/fractal/src/Scope.php on line 419

Why? How to make the result to be an instance of Model in custom query mode?

edited Dec '20

The "Results" section of the documentation mentions this: https://docs.phalcon.io/4.0/en/db-phql#results

Basically, since you're not querying for all columns in the ContestProblem table, it doesn't return you a model object. If it did, where would the data from Contest and Problemgo?

Your choices are:

  1. Adjust your downstream code to handle not dealing with a model.
  2. Use the ORM to get just Contest records, then set up relationships to access each Contest's ContestProblems and Problems