【问题标题】:Laravel not getting Accessor Trying to get property on a non-objectLaravel 没有获取访问器试图获取非对象的属性
【发布时间】:2018-07-29 05:12:59
【问题描述】:

我正在尝试获取地图对象的值以检查用户是否进行了评分。

{{ $book->rated }} 既不返回 false 也不返回 true。

在修补中

$book->getTypeAttribute(); PHP 通知:试图获取的属性 /Applications/MAMP/htdocs/elirating/app/Book.php 中的非对象在线 40

该方法需要获取评分的类型,默认设置为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(这是设置类型的方式,以及我尝试检索值的方式)

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>

图像(只读属性需要有真或假)它既不显示。

【问题讨论】:

  • 可能有几个地方失败了,但我的猜测是在auth()-&gt;user()-&gt;id 中,auth()user() 正在返回一个非对象(字符串、数组等)。您可以将这些调用的结果拆分为不同行的变量,然后查看行号错误是否发生变化。
  • 好的,我要删除身份验证,看看会发生什么
  • 我在 tinker 中得到 null,但用户已经评分,类型需要返回 true 而不是 null

标签: php laravel


【解决方案1】:

您需要在访问器中的查询上调用firstget

return Rate::where(['type' => $this->getKey(), 'user_id' => auth()->id()])->first()

另外,当使用访问器时,你不要调用完整的函数,如getTypeAttribute,你只使用属性名type

// wrong
$book['rated'] = $book->getTypeAttribute();

// right
$book['rated'] = $book->type;

但是,我认为您应该使用existsdoesntExist 查询函数来查找用户是否留下评分。例如:

// this will return true/false
public function getRatedAttribute()
{
    return Rate::where(['type' => $this->getKey(), 'user_id' => auth()->id()])->exists();
}

将属性附加到Book 模型:

// this will add the attribute to each book in the query result.
protected $appends = ['rated']; // or type

那么你可以简单地使用:

$book->rated; // true if a rating exists, otherwise false.

【讨论】:

  • 让我试一试
  • $book-&gt;getTypeAttribute(); 方法有什么问题
  • 函数的 getAttribute 部分用于 Laravel 将其识别为访问器。定义访问器的目的是让您可以创建伪属性并像使用真实属性一样使用它们。
  • $book['rated'] = $book-&gt;type; 不起作用,它不会在data-rateyo-read-only="{{ $book-&gt;rated }}" 内给我一个真假
  • 我已经使用 Laravel 几年了,其中大部分是从阅读文档和从事开源项目中学到的。很高兴听到您成功了。
猜你喜欢
  • 2022-10-08
  • 2018-06-27
  • 2015-09-22
  • 2017-03-20
  • 2014-03-25
  • 2015-01-25
  • 2014-06-23
  • 1970-01-01
相关资源
最近更新 更多