Propel: AND e OR
Le condizioni multiple per una colonna utilizzando Propel come ORM non sono proprio immediate. Lavorando con symfony, che usa proprio Propel, mi sono avvicinato all’orm grazie al libro relativo al framework di sviluppo per PHP5. Chiaramente le nozioni riportate sono relative agli esempi presi in esame di volta in volta e coprono le funzioni principali senza, giustamente, andare troppo nei particolari (da ricercare nella documentazione di Propel). Questo ha fatto sì che mi imbattessi nel problema di applicare condizioni multiple in una query per una stessa colonna.
Usiamo un semplice esempio per mostrare la strada sbagliata, che potrebbe sembrare la più logica non conoscendo Propel, e quella giusta. Ipotizziamo di avere una semplice tabella con due soli campi: “nome” e “numero”. Da questa tabella vogliamo estrarre solo i record che hanno un valore di “numero” compreso tra 11 e 20 (con estremi esclusi).
SELECT *
FROM table
WHERE numero > 11 AND numero < 20
La traduzione errata, più istintiva, è qualcosa di simile alla seguente:
$c = new Criteria();
$c->add(TablePeer::NUMERO, 11, Criteria::GREATER_THAN);
$c->add(TablePeer::NUMERO, 20, Criteria::LESS_THAN);
...
dove si pensa che ogni add vada ad aggiungere una condizione conbinandola alle altre con un AND. Tutto questo però è sbagliato visto che aggiungendo in questo modo più condizioni sulla stessa colonna “sovrascrive” le precedenti e lascia utilizzata solo l’ultima. L’ equivalente di:
SELECT *
FROM table
WHERE numero < 20
che di sicuro non è quello che vogliamo. Come fare allora? Bisogna ricorrere all’utilizzo degli oggetti di tipo Criterion usando il metodo Criterion::addAnd():
$c = new Criteria();
$criterion = $c->getNewCriterion(TablePeer::NUMERO, 11, Criteria::GREATER_THAN);
$criterion->addAnd($c->getNewCriterion(TablePeer::NUMERO, 20, Criteria::LESS_THAN));
$c->add($criterion);
...
In questo modo le due condizioni verranno prese in considerazione allo stesso modo e collegate con un AND. Abbiamo ottenuto l’interpretazione corretta. Per lavorare con l’OR basta cambiare il metodo utilizzato da $criterion->addAnd a $criterion->addOr.




