mardi 12 janvier 2016

Laravel Select CASE relation exists

I have a popular fulltext search package installed on my application but now I need to adjust the relevance column if some relation exists. My problem is that the relations I want to check are very complex and impossible to replicate with joins so the solution like:

$results = MyModel::with('relation1', 'relation2')
                ->someComplexScopeRelation()
                ->distinct()
                ->search($string, $searchableColumns, true)
                ->orderBy('field', 'DESC')
                ->leftjoin('table2', function($q){
                    $q->on('table2.a','=','my_models.b');
                })
                ->select(array('field1','field2', DB:raw('CASE WHEN count(table2.id) > 0 THEN (relevance  + relevance * (count(table2.id) * 0.25)) ELSE relevance END AS relevance')))
                ->get();

is not possible because the relation with table2 includes some complex conditions with other tables. Something like:

public function table2Relationship()
{
    return $this->hasOne('Table2')
                ->where('field', 'value')
                ->where(function($q){
                    $q->where('field', 'value')
                        ->orWhere('field', 'value');
                })
                ->where('field', 'value')
                ->whereHas('AnotherRelation', function($q){
                    $q->where('field', 'value');
                })
                ->whereHas('AnotherRelation2', function($q){
                    $q->where('field', 'value')
                        ->where('field', 'value');
                })
                ->where(function($q){

                    if(CONDITION)
                        $q->where('field', 'value')
                            ->orWhere('field', 'value');
                    else
                        $q->where('field', 'value')
                            ->where(function($q){
                                $q->where('field', 'value')
                                    ->orWhere('field', 'value');
                            })
                });
}

What I need is create multiple CASEs using my relations and if the condition/relation exists THEN I increment or decrement the value of column relevance, initially calculated by package above described and without duplicate code of declared relationship.

I need something like:

$results = MyModel::with('relation1', 'relation2')
                ->someComplexScopeRelation()
                ->distinct()
                ->search($string, $searchableColumns, true)
                ->orderBy('field', 'DESC')
                ->select(array('field1','field2'))
                ->addCaseSelect(function($q) {
                    $q->addCase(function($q) {
                                    $q->has('table2Relationship', function($q){
                                        $q->where('extra_conditions', 'value');
                                    }, '>=', 1);
                                }, 
                                DB::raw('(relevance + relevance * (count_table2Relationship * 0.25))'), //THEN
                                DB::raw('relevance') //ELSE
                        );
                    $q->addCase(function($q) {
                                    $q->has('table3Relationship', function($q){
                                        $q->where('extra_conditions', 'value');
                                    }, '=', 0);
                                }, 
                                DB::raw('relevance - 1'), //THEN
                                DB::raw('relevance') //ELSE
                        );
                }, DB::raw('relevance')) //AS
                ->get();

and should return something like this:

SELECT field1, field2, 
(
    CASE 
        WHEN count(SELECT count(table2.id) FROM table2 WHERE ...) as count_table2Relationship >= 1 THEN (relevance + relevance * (count_table2Relationship * 0.5)) ELSE relevance 
        WHEN count(SELECT count(table3.id) FROM table3 WHERE ...) as count_table3Relationship = 0 THEN relevance - 1 ELSE relevance 
    END
) AS relevance FROM my_models WHERE ...

Anyone knowns a solution for this or a package that fills my needs?

After a couple hours of search I didn't found any package that leads with CASEs conditions (or IF/ELSE). With help I could be available to create a package for this...probably this will rocks!

Thanks!



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire