【发布时间】:2018-09-27 09:42:31
【问题描述】:
我对 Laravel 非常陌生,希望了解一下。
我正在尝试链接两个表:Users => Profiles
Users 看起来像这样:
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('username');
$table->string('displayName');
$table->string('email')->unique();
$table->string('role')->nullable();
$table->string('department')->nullable();
$table->string('location')->nullable();
$table->string('directDialIn')->nullable();
$table->string('mobileNumber')->nullable();
$table->string('managedByUsername')->nullable();
$table->string('managedByDisplayName')->nullable();
$table->timestamps();
});
Profiles 看起来像这样:
Schema::create('profiles', function (Blueprint $table) {
$table->increments('id');
$table->string('user_username')->index();
$table->mediumText('skills');
$table->mediumText('background');
$table->mediumText('socialProfiles');
$table->string('displayPicture')->default('../../assets/images/user_pic.jpg');
$table->string('mangedByUsername');
$table->boolean('changesPending')->default(0);
$table->timestamps();
});
相关模型
class User extends Authenticatable
{
use Notifiable;
/**
* Primary key to use
*/
protected $primaryKey = 'username';
/**
* Tell Eloquent to not auto increment
*/
public $incrementing = false;
/**
* Table to use
*/
protected $table = 'users';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'username', 'displayName', 'email',
'role', 'department', 'location',
'directDialIn', 'mobileNumber', 'managedByUsername',
'managedByDisplayName'
];
/**
* The attributes that should be hidden for arrays.
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* Get the profile associated with this user
*/
public function profile()
{
return $this->hasOne(Profile::class, 'user_username');
}
}
class Profile extends Model
{
/**
* Get the user that has this Profile
*/
public function user()
{
return $this->belongsTo(User::class, 'user_username');
}
}
根据文档:
Eloquent 根据模型名称确定关系的外键。在这种情况下,电话模型被自动假定为具有 user_id 外键。如果您希望覆盖此约定,您可以将第二个参数传递给 hasOne 方法:
所以我已经明确定义了要使用的键。
在我的路线中,我有:
Route::get('/profile/{user}', 'ProfileController@index');
我已经习惯于使用 SQL JOIN 来连接两个表,但在这种情况下,我如何同时获取 User 模型数据和 Profile Model 数据?
所以它会是这样的:用户:Dave 然后是 Dave 的个人资料。
另外,如果 Dave 没有填写他的个人资料,我可以只显示他的用户数据吗?
在ProfilesController 我有这个:
public function index(Request $request)
{
// Get this user's username from the session
$username = $request->session()->get('User_name');
/**
* Get the Profile and associated User by pulling from the database via user_username
* Will return a profile with an attached user
*/
$profile = Profile::with('user')->where('user_username', $username)->first();
return view('pages.profile.show', compact('profile'));
}
但是,当我转储Profile 的结果时,关联的User 为空。
我觉得这很奇怪,因为我可以使用 Artisan tinker 如下:
$profile = App\Profile::find(7);
然后……
$profile->user
这会产生与 ID 为 7 的个人资料相关的用户。
dd($profile); 产生以下结果:
配置文件表
用户表
如您所见,两个表都有数据,user_username 与username 相同,但由于某种原因,在使用with:: 时,两者之间的链接不可见。
【问题讨论】:
-
Profile模型中的外键是什么?如果是user_username,那么您应该在模型或关系中指定它。因为 Eloquent 根据模型名称确定关系的外键。在这种情况下,会自动假定 Profile 模型具有 user_id 外键。 -
我将更新我的问题以显示更详细的规范
-
您的
$profile有数据吗?你如何访问关系?像$profile->user吗? -
这正是我正在尝试的方式。
-
请添加来自
index()方法的dd($profile);结果。在 return 语句之前。
标签: php laravel laravel-5.6