Laravel的问题hasManyThrough关系

时间:2016-09-29 13:20:38

标签: laravel relationships

我在larval中使用hasManythrough关系时遇到问题。只需按照文档使用示例,即:

countries
id - integer
name - string

users
id - integer
country_id - integer
name - string

posts
id - integer
user_id - integer
title - string

以下是我在模型中设置关系的方法

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Country extends Model
{
public function posts() {

    return $this->hasManyThrough('App\Post', 'App\User', 'user_id', 'country_id', 'id');
}
}

以下是用户模型

class User extends Authenticatable
{
use Notifiable;

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

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

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

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

这是帖子模型

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
     public function user() {

    return $this->belongsTo('App\User');
}
}

因此,该网站没有详细介绍如何通过国家模式提取帖子。使用routes文件,这是我使用的查询

Route::get('posts/countries/{id}', function($id) {

$countries = App\Country::where('id', $id)->get();

return $countries->posts;

});

在我看来,就像我按照文档说的那样正确建立关系。用户表上有country_id,因此我不确定查询是否错误,或者我确实错误地设置了关系。

2 个答案:

答案 0 :(得分:0)

您实际上并没有请求这种关系,您只是查看国家/地区的属性。

如果要在查询构建器中预先加载帖子,则需要在构建查询时添加with('posts')。 (在调用执行查询的->get()并将其转换为集合之前。)

Route::get('posts/countries/{id}', function($id) {

$country = App\Country::with('posts')->where('id', $id)->first();

return $country->posts;

});

或者,如果您想延迟加载,可以通过这样做->posts()来询问国家/地区模型的关系:

Route::get('posts/countries/{id}', function($id) {

$country = App\Country::with('posts')->where('id', $id)->first();

return $country->posts();

});

注意:在这两种情况下我都将->get()更改为->first()。我假设您只想要返回一个国家/地区的帖子。

->get()执行查询并将相关模型作为集合返回,->first()从查询中获取第一个模型。

答案 1 :(得分:0)

@Nicklas Kevin Frank

您的解决方案对我不起作用。至少不完全,但你在某些方面是正确的。我修好了,发现查询效果更好:

Route::get('posts/countries/{id}', function($id) {

$country = App\Country::where('id', $id)->first();

return view('country')->with('country', $country);
});

所以,就像你说的那样,它显然需要 - &gt; first()选项,但它不需要with('posts')部分。但非常感谢我的朋友。没有你,我无法解决这个问题。