0

I am trying to fetch the columns from another table through the id but whenever I do I get this error if I use foreach in the view

Property [id] does not exist on this collection instance. (View: C:\xampp\htdocs\myUniMentor\resources\views\userProfile\viewUserProfilePage.blade.php)

but if I run code without foreach command like $users->reviews I get the array of review table and also all the related content to that specific id and doing this $users->reviews->comments gives me an error

Property [comments] does not exist on this collection instance. (View: C:\xampp\htdocs\myUniMentor\resources\views\userProfile\viewUserProfilePage.blade.php)

My questions are:

  1. How can I display the comments using the models?
  2. How $users->reviews is returning only the columns associated with the id? is it because I passed the id in belongsTo()?

ReviewController.php

public function showUserProfile($id) {

        $users = User::find($id);

        // echo $users->first_name;

        return view('userProfile.viewUserProfilePage', compact('users'));
    }
}

 public function addNewReview($id) {

        $stars = Input::get("rating");
        $message = Input::get("message");

        // $users = User::find($id);

        $users = User::where('id', $id)->first();
        // echo $stars;
        // echo $message;
        // echo $users;
        // echo $users->id;
        // echo Auth::user()->id;
        // die();
        $reviews = new Review();
        $reviews->user_id = $users->id;
        $reviews->given_by = Auth::user()->first_name . ' ' . Auth::user()->last_name;
        $reviews->stars = $stars;
        $reviews->comments = $message;

        $reviews->save();

        Session::flash('message','Your Review has been added to the Mentor');
        return redirect('show-user-profile/' . $users->id);
    }

show-user-profile.blade.php

@section('content2')

<h3>Reviews</h3>
<p>{{ $users->reviews->comments }}</p> 

@endsection

Review.php

namespace App;

use Illuminate\Database\Eloquent\Model;
use App\User;

class Review extends Model
{
    protected $fillable = [
        'comments', 'stars', 'given_by',
    ];

    public function users()
     {
         return $this->belongsTo('App\User', 'user_id','id');
     }
}

User.php

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;

use App\UserType;
use App\Subject;
use App\SubjectKeyword;
use App\Review;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'first_name', 'last_name', 'type', 'username', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];

    public function getAllUsers() {
        return User::all();
     }

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

    // public function subjects()
    // {
    //     return $this->belongsToMany('App\Subject');
    // }

    public function subjects(){
        return $this->belongsTo('App\Subject','subject_id','id');
    }

    public function reviews(){
        return $this->hasMany('App\Review');
    }

    public function subjectKeywords(){
        return $this->hasMany('App\SubjectKeyword');
    }
}

2 Answers2

0

It's not clear what you are trying to do in the blade file. But if you want to print all the comments of all the reviews of the user.

Show user profile blade

@section('content2')

    <h3>Reviews</h3>
    @foreach($user->reviews as $review)
        <p>{{ $review->comments }}</p>
    @endforeach 

@endsection

Explanation

reviews() is a one to many relationship of a user, $user->reviews is a collection. So if you want to access any property of a review you need to loop through the collection.

Tharaka Dilshan
  • 4,371
  • 3
  • 14
  • 28
  • thats already been fixed thank you for your answer. Can you please tell me how to order it by latest on the top ? I tried orderBy but not working – Asad Sajjad Aug 05 '19 at 17:32
0

Please change the following:

  1. In your HTML

    @foreach($users->reviews as $review)
     <p>{{ $review->comments }}</p> 
    @endforeach
    
  2. In your Review.php, Since a review belong to a User, Change to

    public function user()
    {
      return $this->belongsTo('App\User');
    }
    
Zadat Olayinka
  • 441
  • 3
  • 8
  • Hello Bundayy Olayinka, thank you for your answer. This worked for me. I understood this but do you mind explaining this so that I know my understanding is right ? – Asad Sajjad Aug 05 '19 at 16:04
  • Great. Based on your mapping, A User has many Reviews, so when you want to get the reviews of a user, you will get a collection, then to display each of them, you need to loop through the collection so you can display the comment in each review. For the second one, Since a Review belongs to a User, then you don't need to give it a plural function name, and you don't need to map it manually since you have a `user_id` field already.Laravel automatically picks the Model name concatenated with `_` and then the primary key, i.e `user_id` where `User` is the model and `id` is the primary key. – Zadat Olayinka Aug 05 '19 at 16:12
  • Thank you. I understood. I have one more question related to this if you could answer. if I have to fetch results from 3 different tables then ? e.g. in this case `$users->review->coments` is finding me comments so what if I add one more model before $users ? will that work ? – Asad Sajjad Aug 05 '19 at 17:13
  • and how can I put the latest record on the top ? I tried orderBy but not working – Asad Sajjad Aug 05 '19 at 17:31
  • to put latest at the top add `orderBy('created_at','desc')`. I didn't quite get the other question you're asking about getting data from another table. Maybe you should be more detailed – Zadat Olayinka Aug 05 '19 at 19:03
  • where am I exactly putting that `orderBy` ? As for second question I am getting all details from keyword table so e.g. its like `foreach($subjectKeyword as $f) {{ $f->users->first_name }}` which is working but when I want display a column from review table in it using the same logic i.e. `foreach($subjectKeyword as $f) {{ $f->users->reviews->average }}` or `foreach($subjectKeyword as $f) {{ $f->users->reviews['average'] }}` it gives me the same error as in this post. I hope you understands now – Asad Sajjad Aug 06 '19 at 12:53
  • I dont know why keep on facing the same issue. May be I am not understanding it well enough to implement it this way. '{{$f->users->reviews}}` does show all records from the table. Basically now facing the same issue as this post but on different page. – Asad Sajjad Aug 06 '19 at 13:16
  • for the orderBy, do this in your foreach `$users->reviews->reverse() as $review` – Zadat Olayinka Aug 06 '19 at 13:41
  • i will need to see your code to help you with your other request – Zadat Olayinka Aug 06 '19 at 13:45
  • do I need to do that in views ? Should I update this post with that code too ? – Asad Sajjad Aug 06 '19 at 13:49