Order by activity date instead of users followed

Viewed 52

I have two tables, the activities table and followings table. I want to get "following" activity the date it was created instead of by the date the user was created.

    Schema::create('activities', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->integer('user_id')->index();
        $table->integer('activity_id')->index();
        $table->string('activity_type', 50);
        $table->timestamps();
        $table->index(['activity_id', 'activity_type']);
    });

    Schema::create('followings', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->integer('user_id');
        $table->unsignedBigInteger('follower_id');
        $table->dateTime('followed_date')->nullable();
        $table->dateTime('unfollowed_date')->nullable();
        $table->timestamps();
        $table->unique(['user_id', 'follower_id']);
    });

Right now I have this code:

Controller:

$followings = $user->following()->get();

View:

@foreach($followings->sortByDesc('id') as $following)

                        @foreach($following->user->activity->sortByDesc('id') as $activity)
                        
                        @if($activity->activity_type == 'App\Thread')
                        <li class="activity">
                            <div class="activity-user">
                                <p class="avatar" style="background-color: {{ $activity->user->color }}">
                                    {{ substr($activity->user->name, 0, 1) }}</p>
                            </div>
                            <div class="activity-body">
                                <h4><a
                                        href="/profiles/{{ $activity->user->name }}?profile-posts">{{ $activity->user->name }}</a>
                                    published <a
                                        href="/forums/{{ $activity->activity->channel->slug }}/{{ $activity->activity->slug }}/">
                                        {{ $activity->activity->title }}</a></h4>
                                <p>
                                    {!! BBCode::parse($activity->activity->body) !!}
                                </p>
                                <p class="created-at">
                                    {{-- {{ $activity->activity->created_at->format('l') }}
                                    at
                                    {{ $activity->activity->created_at->format('h:i A') }} --}}
                                    {{ $activity->activity->created_at->format('M j, Y') }}
                                </p>
                            </div>
                        </li>

                        @endif
                        @endforeach

                        @endforeach

Model:

public function following()
{
    return $this->hasMany(Following::class);
}

Is there anyway for me to reach the polymorphic table and order by the Activity date instead of by the following() date?

Right now, it returns records based on the user's name in the date they posted it, but I would like it strictly by the activity.

2 Answers

For your scenario, you will be better of with a custom DB query like this, I haven't tested it so you will need to adjust for your use case but basic concept for Laravel is pretty much the same.

$following = Following::join('users', 'followings.user_id', '=','users.id')
        ->join('activites', 'users.id', '=', 'activities.user_id')
        ->orderBy('activities.created_at')
        ->select('followings.*')
        ->get();

Here's how I did it:

Controller

    $followings = $user->following()->get();
    foreach($followings as $following) {
        foreach($following->user->activity as $activity) {
            $followingArray[] = $activity->id;
        }
    }
    //dd($followingArray);
    if(!empty($followingArray)){
        $following = Activity::whereIn('id', $followingArray)->orderBy('created_at', 'desc')->get();
    } else {
        $following = '';
    }

View:

                    @if(!empty($following))

                    @foreach($following as $activity)
Related