Php 拉威尔:我应该如何更新这种关系?
假设我有以下表格:Php 拉威尔:我应该如何更新这种关系?,php,database,laravel,eloquent,Php,Database,Laravel,Eloquent,假设我有以下表格: User: -userID -userName ... Exercises: -exerciseID ... 用户型号: <?php use Illuminate\Auth\UserInterface; use Illuminate\Auth\Reminders\RemindableInterface; class User extends Eloquent implements UserInterface, RemindableInterface {
User:
-userID
-userName
...
Exercises:
-exerciseID
...
用户
型号:
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'users';
protected $primaryKey = 'userID';
...
public function hasPassedExercises() {
return $this->hasMany('Exercise', 'exerciseID');
}
}
然而,据我所知,这对任何基础表都没有影响。我试图理解文档,看看它如何应用于我的问题。所以我的问题是,在这里应该采取什么样的正确行动
我是否应该创建一个表
users\u completed\u exercises
,该表将userID
和exerciseID
作为外键,如果是,我在更新时如何将它们链接到我的用户?或者有更优雅的解决方案吗?实际上,您必须使用关系表(称为透视表)
在laravel文档中,您必须使用表名来命名透视表,表名按名称排序(您不必这样做,但最好是这样)。
我们将接受您的命名约定,以便:用户完成练习
所以这里我们应该有这个:
users:
- userId // Unsigned Int PRIMARY KEY AUTO_INCREMENT
Exercises:
- exerciseId // Unsigned Int PRIMARY KEY AUTO_INCREMENT
users_completed_exercises:
- id // Unsigned Int PRIMARY KEY AUTO_INCREMENT
- exerciseId // Unsigned Int FOREIGN KEY REFERECES EXERCICES ON ID
- userId // Unsigned Int FOREIGN KEY REFERECES USERS ON ID
在用户模型上,您应该具有:
public function passedExercises()
{
// Alphabetical order of your id's are here, very important because laravel
// retreives the good ID with your table name.
return $this->belongsToMany('Exercise', 'users_completed_exercises', 'exerciseId', 'userId');
}
运动模型的逆解
public function usersWhoPassed()
{
// Alphabetical order of your id's are here, very important because laravel
// retreives the good ID with your table name.
return $this->belongsToMany('User', 'users_completed_exercises', 'exerciseId', 'userId');
}
检索信息现在非常简单
Route::post('dbm/userPassedExercise', function () {
// Don't use $_POST with laravel, they are exceptions indeed, but avoid as much as
// possible.
$user = User::find(Input::get('userId'));
$exercise = Exercise::find(Input::get('exerciseId'));
// Very important, use () on relationships only if you want to continue the query
// Without () you will get an Exercises Collection. Use ->get() or ->first() to end
// the query and get the result(s)
$exercise->usersWhoPassed()->save($user);
});
您可以轻松地检查用户是否也通过了练习
Route::get('/exercises/{id}/passed_users', function($id)
{
$exercise = Exercise::find($id);
if ($exercise->usersWhoPassed()
->where('userId', '=', Input::get('userId'))->count()) {
return 'User has passed';
}
return 'User has failed';
});
谢谢你的详尽回答。但是,在保存行中找不到错误
类“users\u completed\u exercises”。我需要为透视表制作模型吗?您不必为透视表制作模型。拉威尔为你做的。我没有对实体进行常规检查。在您的exercise::find()之后是否检查$exercise realy是否存在-请原谅我的英语,不是我的母语。我用var\u dump
检查了一下。你能通过var\u dump的结果吗?(小技巧,使用dd(框架方法)而不是var_dump)使用attach()而不是save()将以两种方式工作。在我的开发环境中测试。Attach不会尝试保存实体,而save会。
Route::get('/exercises/{id}/passed_users', function($id)
{
$exercise = Exercise::find($id);
if ($exercise->usersWhoPassed()
->where('userId', '=', Input::get('userId'))->count()) {
return 'User has passed';
}
return 'User has failed';
});