Laravel - 2 SQL Abfragen migieren

Werner S

Neues Mitglied
Grüß euch,

ich habe folgenden Aufbau.

Message.php
PHP:
public function replies()
    {
        return $this->hasMany(Reply::class);
    }

    public function user()
    {
        return $this->belongsTo(User::class);
    }

Reply.php
PHP:
public function message()
    {
        return $this->belongsTo(Message::class);
    }

    public function user()
    {
        return $this->belongsTo(User::class);
    }

Message Table
PHP:
Schema::create('messages', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->unsignedBigInteger('user_id')->unsigned();
            $table->unsignedBigInteger('to_user_id')->unsigned();
            $table->string('title');
            $table->longText('body');
            $table->boolean('attachment')->default(false);
            $table->timestamps();
   
            $table->foreign('user_id')->references('id')->on('users');
            $table->foreign('to_user_id')->references('id')->on('users');
        });

Replies Table
PHP:
Schema::create('replies', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->unsignedBigInteger('user_id')->unsigned();
            $table->unsignedBigInteger('to_user_id')->unsigned();
            $table->unsignedBigInteger('message_id')->unsigned();
            $table->dateTime('status')->nullable();
            $table->string('title')->nullable();
            $table->longText('body');
            $table->boolean('attachment')->default(false);
            $table->timestamps();

            $table->foreign('user_id')->references('id')->on('users');
            $table->foreign('to_user_id')->references('id')->on('users');
            $table->foreign('message_id')->references('id')->on('messages');
        });

Die Daten lese ich folgendermassen aus
PHP:
public function index()
    {
        $pns = Message::where('to_user_id', Auth::user()->id)->paginate(10);
        $replys = Reply::where('to_user_id', Auth::user()->id)->paginate(10);

        return view('message.index', compact('pns', 'replys'));
    }

HTML:
@foreach($replys AS $reply)
<tr>
    <td>
        @if($reply->status == 0)
        <b><a href="{{route('messages.show', $reply->message_id)}}">RE: {{$reply->message->title}}</a></b>
        @elseif($reply->status == 1)
        <a href="{{route('messages.show', $reply->message_id)}}">RE: {{$reply->message->title}}</a>
        @endif
    </td>
    <td><span style="color: {{$reply->user->color}}">{{$reply->user->name}}</span></td>
    <td>{{ Carbon\Carbon::parse($reply->created_at)->format('d.m.Y H:i') }}</td>
    <td>
        <div class="icheck-primary">
            <input type="checkbox" name="status[]" value="{{$reply->id}}" />
            <label for="check1"></label>
        </div>
    </td>
</tr>
@endforeach @foreach($pns AS $pn)
<tr>
    <td>
        @if($pn->status == 0)
        <b><a href="{{route('messages.show', $pn->id)}}">{{$pn->title}}</a></b>
        @elseif($pn->status == 1)
        <a href="{{route('messages.show', $pn->id)}}">{{$pn->title}}</a>
        @endif
    </td>
    <td><span style="color: {{$pn->user->color}}">{{$pn->user->name}}</span></td>
    <td>{{ Carbon\Carbon::parse($pn->created_at)->format('d.m.Y H:i') }}</td>
    <td>
        <div class="icheck-primary">
            <input type="checkbox" name="status[]" value="{{$pn->id}}" />
            <label for="check1"></label>
        </div>
    </td>
</tr>
@endforeach

Soweit funktioniert dies auch. Wie Ihr allerdings dem angehangenem Bild entnehmen könnt, ist die Ausgabe nicht ganz korrekt da ich erst die Antworten und dann die Nachrichten ausgeben. Drehe ich es um, hab ich die gleiche Anzeige, nur Spiegelverkehrt.
Habe ich also 3 Antworten wovon 1 nicht gelesen ist und Nachrichten vowon eine nicht gelesen ist, werden die ungelesenen nicht Untereinander angezeigt.
Kann ich in Laravel irgendwie die beiden Abfragen kombinieren so das immer die neusten Nachrichten aus beiden Tabellen angezeigt werden?
In der Vergangenheit habe ich die Nachrichten und Antworten in eine einzige Tabelle gepackt, da hatte ich das Problem nicht. Dies wollte ich dies mal nicht wieder so machen.
 

Anhänge

  • laravel.png
    laravel.png
    8 KB · Aufrufe: 8
Zuletzt bearbeitet:

JR Cologne

Administrator
Teammitglied
Die einfachste Lösung ist vermutlich, die beiden Ergebnismengen zusammenzufassen.
Hierzu gibt es bei Laravel Collections eine merge()-Methode:

Du kannst die Nachrichten dann natürlich auch nach Belieben sortieren und sonstwie arrangieren.

Eine elegantere Variante wären wahrscheinlich SQL Unions, die es beim Laravel Query Builder ebenfalls gibt: https://laravel.com/docs/8.x/queries#unions

Zu beachten sind dabei allerdings gewisse gewöhnliche Restriktionen bei SQL-DBs, über die du dich informieren solltest.
 
Oben Unten