StackOverflow的朋友们大家好,希望大家度过美好的一天(˘⌣˘)♡(˘⌣˘)
我是Laravel的新手,目前正在学习雄辩的人际关系(hasMany)
很抱歉,这篇文章读得太久了,但是我想弄清楚自己遇到的每一个步骤,直到遇到问题为止,还对不起我的英语不好(⁄ ⁄•⁄ ω⁄•⁄ ⁄)
所以我们开始
在我的用户模型中
public function posts() {
// A user can have many posts
return $this->hasMany('App\Post');
}
在我的帖子模型中
public function owner()
{
// A post belongs to a user
return $this->belongsTo('App\User', 'user_id');
}
在我的帖子表中,我有3条简单记录
|----------------------------------------------------------|
| id | user_id | body | ... | ... |
| 1 | 1 | My first post | ... | ... |
| 2 | 1 | Second post | ... | ... |
| 3 | 1 | Another post | ... | ... |
然后让我们说,我们希望看到id = 1的用户及其创建的所有帖子,因此我使用以下代码:
// AccountController
public function profile($id)
{
$user = App\User::with('posts')->findOrFail($id);
return $user;
}
// Will return data:
{
"id": 1,
"name": "Prof. Angela Runte Jr.",
"email": "mborer@example.org",
...
"posts": [
{
"id": 1,
"user_id": 1,
"body": "My first post",
...
},
{
"id": 1,
"user_id": 1,
"body": "Second post",
...
},
{
"id": 1,
"user_id": 1,
"body": "Another post",
...
}
}
在Blade视图中,我可以简单地获取如下数据:
// in profile.blade.php
$user->name
$user->...
@foreach($user->posts as $post)
// Show each post data
@endforeach
它以我想要的方式完美运行,这要感谢泰勒·奥特威尔(Taylor Otwell)创建了一个了不起的框架(´•ω•`)♡
然后我想到一个主意,让我们创建一个功能,使用户可以发布给其他用户,为什么不呢?我们开始做吧! (✧ω✧)
因此,在我的Post迁移中,我更改了表架构:
发件人:
// Before
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->unsignBigInteger('user_id');
$table->text('body');
$table->timestamps();
收件人:
// After
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->unsignedBigInteger('user_id');
// New column: nullable()
$table->foreign('for_id')->references('id')->on('users')->onDelete('cascade');
$table->unsignedBigInteger('for_id')->nullable();
$table->text('body');
$table->timestamps();
如您所见,我将nullable()放在“ for_id”列中
换句话说,如果for_id为空,则该帖子仅属于发布该帖子的用户
否则,该帖子属于发布该帖子的用户以及目标用户(for_id)。
然后,我跑步
// I only use UserSeeder (wanna keep it simple tho)
php artisan migrate:fresh --seed
现在我们有2个ID为1和2的用户(是!)
|----------------------------------------------------------------------------------------|
| id | name | email | ... | ... |
| 1 | Camden Kulas | lemke.fabian@example.net | ... | ... |
| 2 | Mrs. Roberta Stroman | ybartoletti@example.com | ... | ... |
让我们使用修补程序来创建伪数据
php artisan tinker
>> $user = App\User::first();
=> App\User {#3910
id: 1,
name: "Camden Kulas",
email: "lemke.fabian@example.net",
...
}
>> $user->posts()->create(['body' => 'New first post']);
=> App\Post {#4120
body: "New first post",
user_id: 1,
updated_at: "2020-08-30 03:42:43",
created_at: "2020-08-30 03:42:43",
id: 1,
}
// we create one for Mrs. Roberta Stroman (user with id #2)
>> $user->posts()->create(['for_id' => 2, 'body' => 'Hello there']);
=> App\Post {#3912
for_id: 2,
body: "Hello there",
user_id: 1,
updated_at: "2020-08-30 03:44:18",
created_at: "2020-08-30 03:44:18",
id: 2,
}
所以现在我们的帖子表中有2条记录
|--------------------------------------------------------------------|
| id | user_id | for_id | body | ... |
| 1 | 1 | NULL | New first post | ... |
| 2 | 1 | 2 | Hello there | ... |
我们仍处于用户ID#1
>> $user->posts
=> Illuminate\Database\Eloquent\Collection {#4120
all: [
App\Post {#4125
id: 1,
user_id: 1,
for_id: null,
body: "New first post",
...
},
App\Post {#4128
id: 2,
user_id: 1,
for_id: 2,
body: "Hello there",
...
},
],
}
( ̄ω ̄)好的,到这里,一切正常,让我们尝试使用用户ID#2
在我看来,我希望获得用户ID为2,并且所有帖子都由ID为2,以及其他所有ID为2的帖子
>> $user = App\User::find(2);
=> App\User {#4121
id: 2
name: "Mrs. Roberta Stroman",
email: "ybartoletti@example.com",
...
}
>> $user->posts
=> Illuminate\Database\Eloquent\Collection {#4067
all: [],
}
Σ(°ロ°)帖子是空的,那为什么它是空的?
ఠ͟ಠ然后我尝试使用with()
>> $user = App\User::with('posts')->find(2);
=> App\User {#4120
id: 2,
name: "Mrs. Roberta Stroman",
email: "ybartoletti@example.com",
...
posts: Illuminate\Database\Eloquent\Collection {#4123
all: [],
},
}
(ꐦ°᷄д°᷅)什么?为什么帖子仍然是空的? щ(ºДºщ)
因此,经过数天的搜索和阅读,我仍然不知道如何解决此问题(。╯︵╰。)
然后我尝试更改用户模型:posts()函数
发件人:
public function posts()
{
// A post belongs to a user
return $this->hasMany('App\Post');
}
收件人:
public function posts()
{
// In my logic like:
// Hey I want to fetch all posts that made by this user, **or where all posts that created by others for this user**
// Make sense in human language right?
return $this->hasMany('App\Post', 'user_id')->orWhere('posts.for_id', $this->id);
}
我退出了修补匠,然后再次进入修补匠
>> $user = App\User::first();
// return user id #1
>> $user->posts
// works fine, return all posts
(ಠ益ಠ)现在我面临其他问题
>> $user = App\User::with('posts')->first(); // notice that I'm using with()
// tinker return the desired user, and also return ONLY one post
>> App\User {#4123
id: 1,
name: "Camden Kulas",
email: "lemke.fabian@example.net",
....
posts: Illuminate\Database\Eloquent\Collection {#4130
all: [
App\Post {#4128
id: 1,
user_id: 1,
for_id: null,
body: "New first post",
created_at: "2020-08-30 03:42:43",
updated_at: "2020-08-30 03:42:43",
},
// where is the second post?
],
},
}
然后我尝试使用用户ID#2更改修补匠会话
>> $user = App\User::find(2);
// return user id #2
>> $user = App\User::with('posts')->find(2);
// return user id #2, but no post (only array all)
因此,我无需再提出其他问题
[#1]为什么用户#1只获取一个帖子,而他却创建了2个帖子?
一篇文章没有for_id(NULL),第二篇文章有for_id
[#2]如何使用户ID#2来获取其所有帖子,以及为其创建的帖子?
因为用户模型中的IMHO posts()函数对我来说很有意义,但这不起作用
如果有不清楚的解释,它将及时进行编辑
预先感谢
更新
我发现可以这样简单地获取用户X的所有帖子和用户X的所有帖子:
$user = App\User::find(X);
$posts = $user->posts()->orWhere('for_id', X)->get();
return [
'user' => $user,
'posts => $posts
];
所以现在我想到了这个问题:
如何在$ posts中使用with()?
// Like this
$user = App\User::with('allposts')->find(X);
// Return user X and all posts made by X and posted to user X
// So I can simply get data in view like this:
@foreach ($user->allposts as $post)
// Loop all posts by user X and for user X
@endforeach