【问题标题】:Laravel: Can't access Eloquent relationshipLaravel:无法访问 Eloquent 关系
【发布时间】:2017-02-17 12:26:27
【问题描述】:

我已经制作了 Post 和 User 模型,并定义了两者之间的一对多关系,如下所示:

User.php

<?php

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password', 'profile_picture',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
    public function posts () {
        return $this->hasMany(Post::class,'post_author');
    }
}

Post.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    protected $fillable = [
        'post_title', 'post_content', 'post_author', 'post_type', 'created_at', 'updated_at',
    ];
    public function user() {
        return $this->belongsTo(User::class,'id');
    }
    public function postfields() {
        return $this->hasMany(PostField::class);
    }
}

现在,在我的博客控制器中,我将 Post 类压缩到我的博客视图中,如下所示:

BlogController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;

use App\Post;

use App\User;

class BlogController extends Controller
{
    public function index(Post $post) {
        $blog_posts = Post::with('user')->where('post_type', '=', 'blog')->get();
        return view('blog', compact('blog_posts'));
    }
}

现在我尝试访问博客视图中的关系:

@foreach ($blog_posts as $blog_post)
    <div class="post item">
        {{ $blog_post->post_title }}
        {{ $blog_post->post_content }}
        {{ $blog_post->user->name }}
    </div>
@endforeach

当数据库中只有一篇博客文章时,博客视图中的所有内容都会按原样显示,但是当有多个博客文章时,我收到以下错误:

84794846d554b14eb937f08dfef09b6f1edd91c6.php 第 43 行中的错误异常: 试图获取非对象的属性(查看:C:\MAMP\htdocs\Biota-New\resources\views\blog.blade.php)

任何帮助将不胜感激。

这是 $blog_posts 变量的 DD:

Collection {#198 ▼
  #items: array:2 [▼
    0 => Post {#194 ▼
      #fillable: array:6 [▼
        0 => "post_title"
        1 => "post_content"
        2 => "post_author"
        3 => "post_type"
        4 => "created_at"
        5 => "updated_at"
      ]
      #connection: null
      #table: null
      #primaryKey: "id"
      #keyType: "int"
      #perPage: 15
      +incrementing: true
      +timestamps: true
      #attributes: array:7 [▼
        "id" => 1
        "post_title" => "TEST"
        "post_content" => "Test post"
        "post_author" => 1
        "post_type" => "blog"
        "created_at" => "2016-10-08 14:20:07"
        "updated_at" => "2016-10-08 14:20:07"
      ]
      #original: array:7 [▼
        "id" => 1
        "post_title" => "TEST"
        "post_content" => "Test post"
        "post_author" => 1
        "post_type" => "blog"
        "created_at" => "2016-10-08 14:20:07"
        "updated_at" => "2016-10-08 14:20:07"
      ]
      #relations: array:1 [▼
        "user" => User {#199 ▼
          #fillable: array:4 [▼
            0 => "name"
            1 => "email"
            2 => "password"
            3 => "profile_picture"
          ]
          #hidden: array:2 [▼
            0 => "password"
            1 => "remember_token"
          ]
          #connection: null
          #table: null
          #primaryKey: "id"
          #keyType: "int"
          #perPage: 15
          +incrementing: true
          +timestamps: true
          #attributes: array:9 [▼
            "id" => 1
            "name" => "Sup3rL3on"
            "email" => "codeoncaffeine1@gmail.com"
            "password" => "$2y$10$b6pMtiKt0LcDCeRtTlVJzOL3BvD6Ru1TihbOhM7FOHUscW0daIwGC"
            "profile_picture" => "default-profile-picture"
            "account_type" => 1
            "remember_token" => null
            "created_at" => null
            "updated_at" => null
          ]
          #original: array:9 [▼
            "id" => 1
            "name" => "Sup3rL3on"
            "email" => "codeoncaffeine1@gmail.com"
            "password" => "$2y$10$b6pMtiKt0LcDCeRtTlVJzOL3BvD6Ru1TihbOhM7FOHUscW0daIwGC"
            "profile_picture" => "default-profile-picture"
            "account_type" => 1
            "remember_token" => null
            "created_at" => null
            "updated_at" => null
          ]
          #relations: []
          #visible: []
          #appends: []
          #guarded: array:1 [▼
            0 => "*"
          ]
          #dates: []
          #dateFormat: null
          #casts: []
          #touches: []
          #observables: []
          #with: []
          #morphClass: null
          +exists: true
          +wasRecentlyCreated: false
        }
      ]
      #hidden: []
      #visible: []
      #appends: []
      #guarded: array:1 [▼
        0 => "*"
      ]
      #dates: []
      #dateFormat: null
      #casts: []
      #touches: []
      #observables: []
      #with: []
      #morphClass: null
      +exists: true
      +wasRecentlyCreated: false
    }
    1 => Post {#195 ▼
      #fillable: array:6 [▼
        0 => "post_title"
        1 => "post_content"
        2 => "post_author"
        3 => "post_type"
        4 => "created_at"
        5 => "updated_at"
      ]
      #connection: null
      #table: null
      #primaryKey: "id"
      #keyType: "int"
      #perPage: 15
      +incrementing: true
      +timestamps: true
      #attributes: array:7 [▼
        "id" => 6
        "post_title" => "TEST"
        "post_content" => "Test post"
        "post_author" => 1
        "post_type" => "blog"
        "created_at" => "2016-10-08 14:20:07"
        "updated_at" => "2016-10-08 14:20:07"
      ]
      #original: array:7 [▼
        "id" => 6
        "post_title" => "TEST"
        "post_content" => "Test post"
        "post_author" => 1
        "post_type" => "blog"
        "created_at" => "2016-10-08 14:20:07"
        "updated_at" => "2016-10-08 14:20:07"
      ]
      #relations: array:1 [▼
        "user" => null
      ]
      #hidden: []
      #visible: []
      #appends: []
      #guarded: array:1 [▼
        0 => "*"
      ]
      #dates: []
      #dateFormat: null
      #casts: []
      #touches: []
      #observables: []
      #with: []
      #morphClass: null
      +exists: true
      +wasRecentlyCreated: false
    }
  ]
}

Blog.blade.php

@extends('layouts.front-header')

@section('content')
<style>
    .hero-image {
        background: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.4)), url(images/hero-2.jpg);
    }
</style>


<div class="hero-image hero-image-inner-page">
    <div class="hero-image-inner">
        <div class="text">
            <h1>Blog</h1>
        </div>
    </div>
</div>



<main>
    <section class="blog">
        <div class="container">
        <div class="posts">
        <div class="items">
            <!-- 
            <div class="post item">
                <h3 data-field="post_title"></h3>
                <p data-field="post_content"></p>
                <img src="http://fiddle-earth.com/updates/madsa/img/image00.png" alt="">
                <div class="post-data">
                    <img data-field="author_profile_picture" alt="">
                    <p>posted by <strong data-field="post_author"></strong> on <span data-field="post_date"></span></p>
                </div>
            </div> -->


            @foreach ($blog_posts as $blog_post)
                <div class="post item">
                    <h3 data-field="post_title">{{ $blog_post->post_title }}</h3>
                    <p data-field="post_content">{{ $blog_post->post_content }}</p>
                    <!-- <img src="http://fiddle-earth.com/updates/madsa/img/image00.png" alt=""> -->
                    <div class="post-data">
                        <img data-field="author_profile_picture" alt="">
                        @if($blog_post->user()!=null)
                            {{ $blog_post->user->name }}
                        @endif
                        <p>posted by <strong data-field="post_author"></strong> on <span data-field="post_date"></span></p>
                    </div>
                </div>
            @endforeach

        </div>
        <!-- <a href="#" class="items-load">Load more</a> -->
        </div>
        </div>
    </section>
</main>




<script src="assets/js/loadmore.js"></script>
<script>
$('.posts').loadmore({
    source: 'assets/js/json/blog-json.php',
    img: 'uploads/',
    step: 4
});
</script>
@endsection

【问题讨论】:

    标签: php laravel


    【解决方案1】:

    据我所知, Post 模型中的 User 关系导致了异常。所以,当你打电话时:

    {{ $blog_post->user->name }}
    

    找不到与该帖子关联的用户。我猜User 表的外键与 Laravel 的guessed 不同:

    Eloquent 通过检查关系方法的名称并在方法名称后加上 _id 来确定默认的外键名称。但是,如果 Comment 模型上的外键不是 post_id,您可以将自定义键名称作为第二个参数传递给 belongsTo 方法:

    public function post()
    {
        return $this->belongsTo('App\Post', 'foreign_key');
    }
    

    所以在你的情况下,它会是这样的:

    public function user()
    {
        return $this->belongsTo('App\User', 'post_user_id'); //Replace post_user_id with the id convention you are using.
    }
    

    更新:

    感谢您在 $blog_posts 上的 dd。我可以看到正在获取用户,但没有正确调用它。它是一个函数,因此您需要将其视为一个函数。修改您的刀片文件以检索用户,如下所示:

    {{ $blog_post->user()->name }}
    

    这应该得到有效的用户集合。

    更新 2:

    从转储中可以看出,第二个Post 的用户关系为空。在创建帖子并在刀片中处理它时确保它不为空,将其包装在一个空检查中:

    @foreach ($blog_posts as $blog_post)
    <div class="post item">
        {{ $blog_post->post_title }}
        {{ $blog_post->post_content }}
        @if($blog_post->user()!=null)
            {{ $blog_post->user()->name }}
        @endif
    </div>
    @endforeach
    

    更新 3:

    它实际上应该作为属性而不是函数调用,因为它在作为函数调用时返回“BelongsTo”。立即尝试以下操作:

    @foreach ($blog_posts as $blog_post)
    <div class="post item">
        {{ $blog_post->post_title }}
        {{ $blog_post->post_content }}
        @if($blog_post->user!=null)
            {{ $blog_post->user->name }}
        @endif
    </div>
    @endforeach
    

    我在这里重现了同样的问题,这解决了它。让我知道它是否适合你。

    【讨论】:

    • 嘿,我刚刚更新了问题,以便包含外键参数,不幸的是我得到了一个不同的错误。感谢您的回答。你对新的错误有什么想法吗>
    • 能否请您dd$blog_posts 放入您的 BlogsController 并将输出粘贴到此处,以便我可以实际看到发生了什么。 dd($blog_posts);
    • 刚刚添加到问题中,希望对您有所帮助。
    • @6rs_Leon 能否请您展开第一个帖子,然后展开 Original 锚点及其上的所有子树。同时展开Relations 锚点及其所有子树。目标是查看user 是什么。
    • 完整结构现已添加到问题中。
    【解决方案2】:

    我没有发现错误尝试

    composer dump-autoload

    php artisan view:clear

    【讨论】:

      【解决方案3】:

      试试这个:

      而不是

      @foreach ($blog_posts as $blog_post)
          <div class="post item">
              {{ $blog_post->post_title }}
              {{ $blog_post->post_content }}
              {{ $blog_post->user->name }}
          </div>
      @endforeach
      

      使用以下内容:

          @foreach ($blog_posts as $blog_post)
                  <div class="post item">
                      {{ $blog_post->post_title }}
                      {{ $blog_post->post_content }}
                      @foreach($blog_post->user as $user)
                          {{ $user->name }}
                      @endforeach
          @endforeach
      

      【讨论】:

      • 返回如下错误:尝试获取非对象的属性(查看:C:\MAMP\htdocs\Biota-New\resources\views\blog.blade.php)
      • 尝试将函数重命名为 users() 并在你的刀片视图中尝试用户,看看它是否有任何不同。尝试重新启动您的服务器。
      • 我在另一个问题中看到了你的答案,那是因为第二个 DD(blog_posts) 给你回了:#relations: array:1 [▼ "user" => null ] 所以 user = null意味着你得到的就是你应该得到的!
      猜你喜欢
      • 1970-01-01
      • 2020-07-03
      • 2015-10-13
      • 1970-01-01
      • 2015-03-09
      • 1970-01-01
      • 2015-06-27
      • 1970-01-01
      • 2020-02-08
      相关资源
      最近更新 更多