Laravel-datatables: Laravel-Beziehung, wobei die Klausel beim Sortieren von Laravel-Datentabellen nicht gilt

Erstellt am 15. Aug. 2017  ·  14Kommentare  ·  Quelle: yajra/laravel-datatables

Zusammenfassung des Problems oder der Funktionsanfrage

Hallo
Verzeihung
Ich bin nicht gut in Englisch;
Suche funktioniert mit verwandten Modellen
aber wenn ich als verwandtes Feld sortieren möchte, wird es dupliziert
weil übersetzen, wo die Klausel beim Sortieren nicht anwendbar ist

irgendeine Lösung ?

Code-Snippet des Problems

Systemdetails

  • Linux
  • PHP-Version: 7.1
  • Laravel-Version: 5.4
  • Laravel-Datentabellen Version : 7.0
enhancement for review

Alle 14 Kommentare

 class OrderFood extends Model
{
    protected $table = 'order_foods';
    protected $fillable = [
        'order_id','food_id','quantity','food_price'
    ];

    public function order()
    {
        return $this->belongsTo(Order::class);
    }

    public function food()
    {
        return $this->belongsTo(Food::class)
            ->with('translate');
    }
}


class Food extends Model
{
    protected $table = 'foods';
    protected $fillable = [
        'title','date','tax','tax_enabled','tax_included','images','star','description','recipes','status','lang'
    ];

    public function translate()
    {
        return $this->hasOne(FoodTranslator::class,'food_id')
            ->where('lang',app()->getLocale());
    }
}

    public function query()
    {
        DB::statement(DB::raw('set @rownum=0'));
        DB::statement(DB::raw('SET collation_connection = utf8_general_ci'));
        DB::statement(DB::raw('SET character_set_connection = utf8'));
        $order_id = $this->order_id;
        $order_foods = Order::find($order_id)->foods()->with(['food.translate'])->select(['*','order_foods.created_at',DB::raw('<strong i="5">@rownum</strong>  := <strong i="6">@rownum</strong>  + 1 AS rownum')]);
        return $this->applyScopes($order_foods);
    }


    private function getColumns()
    {
        return [
            ['title' => trans('form.row'),'name' => 'rownum', 'data' => 'rownum','searchable'=>false],
            ['title' => trans('order.order_food'),'name' => 'food.translate.title', 'data' => 'food.translate.title','orderable'=>false],
            ['title' => trans('order.quantity'),'name' => 'quantity', 'data' => 'quantity'],
            ['title' => trans('order.food_price'),'name' => 'food_price', 'data' => 'food_price'],
            ['title' => trans('form.created_at'),'name' => 'created_at', 'data' => 'created_at'],
            ['title' => trans('form.action'),'name' => 'action', 'data' => 'action','searchable'=>false,'exportable'=>false,'printable'=>false],
        ];
    }

Dieses Problem wurde bereits auf v8 behoben. Es ist kompatibel zu Laravel 5.4, hat aber grundlegende Änderungen. Beachten Sie jedoch, dass es noch nicht als stabil gekennzeichnet ist. Danke!

Danke vielmals!

Dieses Problem wird in v8 nicht behoben

Ich sollte meine Codes ändern?

Das Problem hier ist die Übersetzungsbeziehung, oder?

public function translate()
{
    return $this->hasOne(FoodTranslator::class,'food_id')
        ->where('lang',app()->getLocale());
}

Das Problem ist, dass die Where-Klausel nicht angewendet wird? Dies wurde in v8 behoben, es sei denn, es gibt ein anderes Problem, das ich nicht sehe?

bei der Bestellung werden 3 Abfragen ausgeführt

1:
bindings:[]
query:"select count(*) as aggregate from (select '1' as `row_count` from `foods`) count_row_table"
time:0.29
2:
bindings:[]
query:"select *, <strong i="6">@rownum</strong>  := <strong i="7">@rownum</strong>  + 1 AS rownum from `foods` left join `food_translator` on `food_translator`.`food_id` = `foods`.`id` order by `food_translator`.`title` desc limit 10 offset 0"
time:0.81
3:
bindings:["fa", 1]
query:"select * from `food_translator` where `lang` = ? and `food_translator`.`food_id` in (?)"
time:0.46

vielleicht muss die where-Klausel in der zweiten Abfrage stehen, nicht 3

diese Abfrage

query:"select * from `food_translator` where `lang` = ? and `food_translator`.`food_id` in (?)"

ist für

public function translate()
{
    return $this->hasOne(FoodTranslator::class,'food_id')
        ->where('lang',app()->getLocale());
}

das keinen Einfluss auf die Ergebnisse hat

@aliworkshop Ich glaube, ich sehe das Problem jetzt. Werde das bei Gelegenheit weiter graben.

vielen dank meister :)

Fehler ist nicht behoben?

Ich habe ein Problem mit der Bearbeitung der EloquentDataTable-Klasse im Namespace Yajra\DataTables behoben

protected function joinEagerLoadedColumn($relation, $relationColumn)
    {
        $table     = '';
        $lastQuery = $this->query;
        foreach (explode('.', $relation) as $eachRelation) {
            $model = $lastQuery->getRelation($eachRelation);
            $fillable = [];
            switch (true) {
                case $model instanceof BelongsToMany:
                    $pivot   = $model->getTable();
                    $pivotPK = $model->getExistenceCompareKey();
                    $pivotFK = $model->getQualifiedParentKeyName();
                    $this->performJoin($pivot, $pivotPK, $pivotFK);

                    $related = $model->getRelated();
                    $table   = $related->getTable();
                    $tablePK = $related->getForeignKey();
                    $foreign = $pivot . '.' . $tablePK;
                    $other   = $related->getQualifiedKeyName();

                    $lastQuery->addSelect($table . '.' . $relationColumn);
                    $this->performJoin($table, $foreign, $other);

                    break;

                case $model instanceof HasOneOrMany:
                    $table   = $model->getRelated()->getTable();
                    $foreign = $model->getQualifiedForeignKeyName();
                    $other   = $model->getQualifiedParentKeyName();
                    $fillable = $model->getRelated()->getFillable();
                    break;

                case $model instanceof BelongsTo:
                    $table   = $model->getRelated()->getTable();
                    $foreign = $model->getQualifiedForeignKey();
                    $other   = $model->getQualifiedOwnerKeyName();
                    break;

                default:
                    throw new Exception('Relation ' . get_class($model) . ' is not yet supported.');
            }
            $this->performJoin($table, $foreign, $other,'inner',$fillable);
            $lastQuery = $model->getQuery();
        }

        return $table . '.' . $relationColumn;
    }

protected function performJoin($table, $foreign, $other, $type = 'left', $fillable = [])
    {
        $joins = [];
        foreach ((array) $this->getBaseQueryBuilder()->joins as $key => $join) {
            $joins[] = $join->table;
        }

        if (! in_array($table, $joins)) {
            $this->getBaseQueryBuilder()->join($table, $foreign, '=', $other, $type);
            if (in_array('lang',$fillable))
                $this->query->where('lang', app()->getLocale());
        }
    }

diese Änderung wendet die lang Spalte wo-Klausel manuell an, um der Abfrage beizutreten

wenn es eine Möglichkeit gegeben hätte, diese Beziehung, in der Klauseln wie folgt gelten würden,
es wäre sehr gut

@aliworkshop danke, aber die vorgeschlagene Lösung funktioniert nur in Ihrem Fall. Kannst du es vielleicht mit dem folgenden Code versuchen?

Ersetzen:

$this->getBaseQueryBuilder()->join($table, $foreign, '=', $other, $type);

Mit:

$this->query->join($table, $foreign, '=', $other, $type);

Ein bisschen beschäftigt mit Arbeitsprojekten und kann in letzter Zeit nicht viel Zeit für oss aufwenden. Danke!

hallo nochmal meister
Ich finde eine andere Lösung für dieses Problem
Wenn wir die EloquentDataTable-Klasse im Namespace Yajra\DataTables so bearbeiten, funktioniert es wahrscheinlich

protected function joinEagerLoadedColumn($relation, $relationColumn)
    {
        $table     = '';
        $lastQuery = $this->query;
        foreach (explode('.', $relation) as $eachRelation) {
            $model = $lastQuery->getRelation($eachRelation);
            switch (true) {
                case $model instanceof BelongsToMany:
                    $pivot   = $model->getTable();
                    $pivotPK = $model->getExistenceCompareKey();
                    $pivotFK = $model->getQualifiedParentKeyName();
                    $this->performJoin($pivot, $pivotPK, $pivotFK);

                    $related = $model->getRelated();
                    $table   = $related->getTable();
                    $tablePK = $related->getForeignKey();
                    $foreign = $pivot . '.' . $tablePK;
                    $other   = $related->getQualifiedKeyName();

                    $lastQuery->addSelect($table . '.' . $relationColumn);
                    $this->performJoin($table, $foreign, $other);

                    break;

                case $model instanceof HasOneOrMany:
                    $table   = $model->getRelated()->getTable();
                    $foreign = $model->getQualifiedForeignKeyName();
                    $other   = $model->getQualifiedParentKeyName();
                    break;

                case $model instanceof BelongsTo:
                    $table   = $model->getRelated()->getTable();
                    $foreign = $model->getQualifiedForeignKey();
                    $other   = $model->getQualifiedOwnerKeyName();
                    break;

                default:
                    throw new Exception('Relation ' . get_class($model) . ' is not yet supported.');
            }
            $wheres = $model->getQuery()->getQuery()->wheres;
            $this->performJoin($table, $foreign, $other,'inner',$wheres);
            $lastQuery = $model->getQuery();
        }

        return $table . '.' . $relationColumn;
    }


    protected function performJoin($table, $foreign, $other, $type = 'left', $wheres = [])
    {
        $joins = [];
        foreach ((array) $this->getBaseQueryBuilder()->joins as $key => $join) {
            $joins[] = $join->table;
        }

        if (! in_array($table, $joins)) {
            $this->query->join($table, $foreign, '=', $other, $type);
            foreach ($wheres as $where) {
                if ($where['boolean'] == 'and')
                    $this->query->where($where['column'], $where['operator'], $where['value']);
                else
                    $this->query->orWhere($where['column'], $where['operator'], $where['value']);
            }
        }
    }

Bitte wenden Sie diesen Code in der nächsten Version an

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

ghost picture ghost  ·  3Kommentare

hohuuhau picture hohuuhau  ·  3Kommentare

josiahke picture josiahke  ·  3Kommentare

ahmadbadpey picture ahmadbadpey  ·  3Kommentare

kamrava picture kamrava  ·  3Kommentare