Search code examples
laravellaravel-5laravel-5.5relationships

How can I get submitted testimonials for a user written by other users


I have a problem with getting all the testimonials submitted by other users to display them on the user profile of the user concerned (the user being reviewed).

There are two tables. First the users table with id, name, email, photo, phone and title. And I have an avis table which stores the testimonials with id, profile_id, user_id and the comment. (The user_id gets the id of the User submitting the form and profile_id gets the id of the User who is receiving the testimonial).

I tried doing it like the following and don't really know if its the right approach. And I am not sure if I did the relationship right. I am kind of new to Laravel. But anyway this is what I tried so far:

This is User model:

public function avis()
{
    return $this->hasMany('App\Avis', 'profile_id', 'user_id');
}

And this is my Avis model:

protected $fillable = ['comment','profile_id'];

public function user() 
{
    return $this->belongsTo('App\User');
}

This is what I did in the controller displaying the profile and list of testimonials:

public function Details($id)
{
    $detail = User::with(['area.town', 'services'])->find($id);

    $avis = User::whereHas('avis', function ($query) use ($id) {
            $query->where('profile_id', '=', $id);
        })
        ->limit(3)
        ->get();

    //dd($avis);

    return view('Users', compact('avis', 'detail'));
}

Here is my form that is used to write a testimonial:

<div id="avisForm"> 
    <p class="feedback_message">We are here to make sure you are sastified and your transactions are safe. We do appreciate and will respond quickly to any feedback from you.</p>

    {!! Form::open(['route' => 'avis.store']) !!}

    <input type="hidden" name="profile_id" value="{{ $detail>id }}">
    {!! Form::textarea('comment', null, ['placeholder' => 'Message', 'required' => 'required']) !!}
    {!! Form::submit('Envoyez', ['class' => 'formBtn','style' => 'margin-top:10px']) !!}

    {!! Form::close() !!}
</div>

And this is the controller method used to store the testimonial:

public function store(AvisCreateRequest $request)
{
    $avis = new Avis;
    $id = Auth::user()->id;

    $avis->comment = $request->comment;
    $avis->profile_id = $request->profile_id;
    $avis->user_id = $id;

    //dd($avis);

    $avis->save();

    return back()->with('success_message', 'Votre Avis a ete envoyez avec succes!');
}

Can someone please point out to me what I am doing wrong?


Solution

  • You will need two different relationships on your User model if you want to be able to query both types of Avis, the ones the User has written and the ones he received.

    public function receivedAvis()
    {
        return $this->hasMany('App\Avis', 'profile_id', 'id');
    }
    
    public function writtenAvis()
    {
        return $this->hasMany('App\Avis', 'user_id', 'id');
    }
    

    You can then query the received testimonials like this:

    public function Details($id)
    {
        $user = User::with(['area.town', 'services'])->find($id);
    
        $avis = $user->receivedAvis()
            ->limit(3)
            ->get();
    
        return view('Users', compact('avis', 'user'));
    }
    

    If you want, you can also use relationship loading on the User - then you don't have to pass multiple variables to your view. It would look something like this:

    public function Details($id)
    {
        $user = User::with(['area.town', 'services'])->find($id);
    
        $user ->load(['receivedAvis' => function ($query) {
            $query->limit(3);
        }]);
    
        return view('Users', compact('user'));
    }
    

    You can then access your testimonials in the view through your $user variable:

    @if(count($user->receivedAvis) > 0)
        <div id="testimonials">
            @foreach($user->receivedAvis as $avis)
                <!-- place the code to display your testimonials here -->
            @endforeach
        </div>
    @endif
    

    Please note that I renamed your $detail variable to $user because it is better to use variable names that reflect the type of the variable.