temuri
temuri

Reputation: 2807

Phalcon\Mvc\Model::find() together with Phalcon\Mvc\Model\Query\Builder

I am trying to use Phalcon\Mvc\Model\Query\Builder object together with Phalcon\Mvc\Model::find() method to customize data load behaviour.

All model rows in the table have "record_status" field which is used to mark records active/inactive.

I intend to extend Model::find() and Model::findFirst() methods to always add "record_status=1" constraint to all my Model queries. But for now, I'm just trying to pass Query\Builder object on to ::find() method externally:

class User extends Phalcon\Mvc\Model
{
}

$user = new User();

/**
 * @var Phalcon\Mvc\Model\Query\Builder
 */
$query = $user->getModelsManager()->createBuilder();

$query->where('email = :email:', [
    'email' => '[email protected]'
])->andWhere('record_status = :status:', [
    'status' => 1
])->from('users');

$found = $user->find($query);

foreach ($found as $foundUser) {
    ...
}

The problem is that ->find($query) returns ALL rows from the database, ignoring WHERE clauses set to $query.

When inspecting properties of $query & $user I see the following relevant protected properties:

$query::_conditions = '(email = :email:) AND (record_status = :status:)';
$query::_bindParams = array(
    'email' => '[email protected]',
    'status' => 1
);

$user::_count = 4; // This is wrong, this corresponds to TOTAL number of rows
$user::_result->_bindParams = NULL; // Bound parameters have disappeared
$user::_result->_sqlStatement = 'SELECT `users`.`id`,  `users`.`email`, `users`.`record_status` FROM `users`'; // As you can see, there is no WHERE clause

I'm on Phalcon 1.3.0, PHP 5.5.1.

I expect find() and findFirst() methods to accept Query\Builder() object and fetch the correct records. Is this a bug or am I approaching it incorrectly?

Thanks, Temuri

Upvotes: 1

Views: 9310

Answers (1)

jodator
jodator

Reputation: 2465

Yep you have things wrong.

The Model::find() and Model::findFirst() functions accept arrays, int or string and are wrappers for query builder.

You have at least two options:

a) use query builder directly:

// ... here is your query builder script as in question
$results = $query->getQuery()->execute();
$firstFound = $results->getFirst();

b) pass array to Model::findFirst():

$firstFound = User::findFirst(
    array(
        '(email = :email:) AND (record_status = :status:)',
        'bind' => array('email' => '[email protected]', 'status' => 1)
   )
);

Upvotes: 3

Related Questions