Closed spacebiscuit closed 7 years ago
The options you provide are just passed-through to the finder: https://github.com/ypnos-web/cakephp-datatables/blob/master/src/Controller/Component/DataTablesComponent.php#L137
Can you check if it works as expected when you call the table finder directly?
Thanks - I figured and found where the finder is called for the model, unfortunately passing the 'matching' array didn't work, however I did manage to get it to work as follows:
$data = $table->find($finder);
if(isset($options['contain'])){
$data->contain($options['contain']);
}
if(isset($options['conditions'])){
$data->where($options['conditions']);
}
if(isset($options['matching'])){
foreach ($options['matching'] as $key => $match) {
$data->matching($key, function ($q) use ($match) {
return $q->where($match);
});
}
}
I am setting my 'matching' option as follows:
$conditions[]; $contain[] = 'Vehicles'; $matching['Vehciles'] = ['Vehicles.id IN' => [1,2,3]];
$data = $this->DataTables->find('Listings', 'all', ['conditions' => $conditions, 'contain' => $contain, 'matching' => $matching]);
For the matching array I found I had to set the key to be the model which we want to match. I'm not sure if this is the most efficient way of doing this but I do get the expected results.
I could create a PR if you think this is an agreeable solution.
First of all, there is no sense in replicating contains and conditions, as these already work as expected.
Second, I believe that the real issue at hands is that there is no matching
option key for querys. Here is a list of recognized options I found in Cake\ORM\Query
:
* - fields: Maps to the select method * - conditions: Maps to the where method * - limit: Maps to the limit method * - order: Maps to the order method * - offset: Maps to the offset method * - group: Maps to the group method * - having: Maps to the having method * - contain: Maps to the contain options for eager loading * - join: Maps to the join method * - page: Maps to the page method
I understand that it is inconvenient not to be able to pass matching from the Controller right now. However what you can easily do is to write a custom finder in the Listings table that does the matching call for you. For example:
public function findMatching(Query $query, array $options)
{
foreach ($options['matching'] as $key => $match) {
$query->matching($key, function ($q) use ($match) {
return $q->where($match);
});
}
return $query;
}
Then you can call $this->DataTables->find('Listings', 'matching', …
. Obviously, you don't have to keep it as generic but can make your finder more specific to your needs.
For the future I suggest:
matching
option to querys, if appropriateThank you Ypnos - that's a very elegant solution. I agree that there is little point in replicating the 'contain' and 'condition' features since this already works. Your solution is an approach I wouldn't have thought of and is good practice for me.
Hi Ypnos!
Is it possible to add 'matching' to the options paramater when calling dataTables. For example
Listings hasMany ListingsUsers
My $options paramater:
The condition and contain are applied but not the matching to filter. Perhaps the solution is to pass a join in the $options?
Thank you in advance for your time.