Reputation: 3589
I'm trying to get the value of a map object to check if a user made a rating or not.
{{ $book->rated }}
is returning neither false or true.
in tinker
$book->getTypeAttribute(); PHP Notice: Trying to get property of non-object in /Applications/MAMP/htdocs/elirating/app/Book.php on line 40
This method needs to get the type of the rating, the default value is set to false
public function getTypeAttribute(){
return Rate::where('type', $this->attributes['id'])->where('user_id',auth()->user()->id) === self::RATED;
}
Book.php
use Illuminate\Database\Eloquent\Model;
use willvincent\Rateable\Rateable;
use App\User;
use App\Rate;
class Book extends Model
{
use Rateable;
const RATED = "true";
const NOT_RATED = "false";
protected $fillable = [ 'user_id', 'title', 'description'];
public function scopeGetBook($query, $book_name )
{
return $query->where('slug', $book_name );
}
public function setTitleAttribute($value)
{
$this->attributes['title'] = $value;
$this->attributes['slug'] = str_slug($value);
}
public function scopeGetBookUser($query, $user_id)
{
return $query->where('user_id', $user_id )->first();
}
public function getTypeAttribute(){
return Rate::where('type', $this->attributes['id'])->where('user_id',Auth()->user()->id) === self::RATED;
}
Rate.php
<?php
namespace App;
use App\User;
use Illuminate\Database\Eloquent\Model;
use willvincent\Rateable\Rateable;
class Rate extends Model
{
protected $fillable = [
'user_id',
'type',
'rating'
];
public $timestamps = false;
protected $table = 'ratings';
}
BookController.php (this is how the type is being set, and how im trying to retrieve the value)
public function rate(Request $request, $book_id)
{
$book = Book::find($book_id);
$rating = $book->ratings()->where('user_id', auth()->user()->id)->first();
if(is_null($rating)){
$ratings = new Rating();
$ratings->rating = $request['rating'];
$ratings->user_id = auth()->user()->id;
$ratings->type = Book::RATED;
$book->ratings()->save($ratings);
return json_encode($book);
}
else{
return response()->json(['status' => 'You already left a review']);
}
}
public function show($book_name)
{
$books = Book::with('ratings')->GetBook($book_name)->get();
$data = $books->map(function(Book $book){
$book['rated'] = $book->getTypeAttribute();
return $book;
});
return view('books.show', compact('data', $data));
}
HTML
<div id="rateYo" data-rateyo-rating="{{ $book->userSumRating or 0}}" data-rateyo-read-only="{{ $book->rated }}" > ></div>
image(the read-only attribute needs to have either true of false) it doesn't show neither.
Upvotes: 1
Views: 1316
Reputation: 18187
You need to call first
or get
on the query in the accessor:
return Rate::where(['type' => $this->getKey(), 'user_id' => auth()->id()])->first()
Also, when using accessors, you don't call the full function, as in getTypeAttribute
, you only use the attribute name, type
.
// wrong
$book['rated'] = $book->getTypeAttribute();
// right
$book['rated'] = $book->type;
However, I think what you should be doing to find if a user has left a rating is to use the exists
or doesntExist
query functions. For example:
// this will return true/false
public function getRatedAttribute()
{
return Rate::where(['type' => $this->getKey(), 'user_id' => auth()->id()])->exists();
}
Append the attribute to the Book
model:
// this will add the attribute to each book in the query result.
protected $appends = ['rated']; // or type
Then you can simply use:
$book->rated; // true if a rating exists, otherwise false.
Upvotes: 2