sci*_*lot 8 php relational-database eloquent
我正在尝试构建一组Eloquent模型,它们代表现有的硬件设备数据库(两者都不能更改).我知道如何在SQL中执行此操作,但我正在努力构建一个使用第三个表的模型关系,类似于关系/联结表,但与复合键一对一关系.
有三个实体(简化):
用户可以同时在许多设备中,并具有与这些设备相关联的会话日志.用户确实拥有唯一的ID,但从设备的角度来看,它们只有一个"用户号",它只是短(3个字节),因此不能代表整个用户范围,因此它映射在device_user表中.(它实际上比这更复杂,但出于这个问题的目的,我已经将其剥离了)
设备表:
d_id PK
[data fields...]
Run Code Online (Sandbox Code Playgroud)
device_user表:
du_uid User's actual ID
du_device_id FK to device.d_id
du_number 000-999
[metadata...]
Run Code Online (Sandbox Code Playgroud)
会话表:
s_device_id device.d_id
s_user_number 000-999 (device_user.du_number)
[data fields...]
Run Code Online (Sandbox Code Playgroud)
场景:我有一个会话,我想查找特定的device_user.d_uid.在SQL中我会做类似的事情:
SELECT session.blah, du_uid
FROM session
INNER JOIN device_user ON du_device_id = s_device_id AND du_number = s_user_number
Run Code Online (Sandbox Code Playgroud)
所以我想这实际上只是一个复合键的关系.
我在Eloquent中尝试的是这样的:
class SessionLogModel {
public function device(){
return $this->belongsTo('MyModels\\DeviceModel', 's_device_id', 'd_id');
}
public function user(){
return $this->belongsTo('MyModels\\DeviceUserModel', 's_user_number', 'du_number')
// A) I tried:
->withDevice($this->s_device_id);
// or B) I tried:
->withDevice($this->device());
}
// example usage
public static function getRecentUser(DateTime $localTime, $deviceId){
$u = null;
// get the preceding session log
$q = SessionLogModel::where('session_type', '=', 'S')
->where('session_device_id', '=', $deviceId)
->where('sesison_date', '<=', $localTime)
->orderBy('session_id', 'DESC')
->take(1)
->with('device')
->with('user');
$s = $q->get()->first();
$u = $s->user->du_uid; // use the unique user ID
...
}
}
class DeviceUserModel {
// A)
public function scopeWithDevice($query, $device_id){
return $query->where('du_device_id', '=', $device_id);
}
// OR B) I tried:
public function scopeWithDevice($query, $device){
return $query->where('du_device_id', '=', $device->d_id);
}
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试了很多方法来限制匹配到两个具有范围或其他"where"结构的列,但似乎总是很难通过BelongsTo"发送"正确的值.在检查DB :: getQueryLog时,设备ID以NULL形式出现.但是,如果我在属性中硬编码值,我可以看到它"正常工作".
我对此进行了相当多的研究,但我发现很难找到类似的结构.
我使用Laravel v4.2中的Eloquent独立使用(不在Laravel中).
以上基于范围的方法是否有效?或者我应该看一个不同的方法?
我刚刚遇到了这个有趣的问题:我厌倦了在 laravel 中模拟你的表,如下所示:
public function up(){
Schema::create('session', function (Blueprint $table) {
$table->increments('id');
$table->integer('s_device_id');
$table->string('s_user_number',20);
$table->timestamps();
});
Schema::create('device', function (Blueprint $table) {
$table->increments('d_id');
$table->string('blah',20);
$table->timestamps();
});
Schema::create('device_user', function (Blueprint $table) {
$table->integer('du_device_id')->unsigned();
$table->integer('du_uid')->unsigned();
$table->string('du_number',20);
$table->primary(['du_device_id', 'du_uid']);//important composite key
$table->timestamps();
});
}
//then do the relations on Medels:
//User Model
public function deviceUser(){
return $this->hasOne(DeviceUser::class,'du_uid');
}
//Device Model
public function deviceUser(){
return $this->hasOne(DeviceUser::class,'du_device_id','d_id');
}
//DeviceUser Model
public function device(){
return $this->belongsTo(Device::class,'du_device_id','d_id');
}
public function user(){
return $this->belongsTo(User::class,'du_uid');
}
//Session Model //[Not the Session Facade of Laravel]
public function device(){
return $this->belongsTo(Device::class,'s_device_id');
}
//Now let us do the work in SessionController after filling your tables with demo data for e.g.
//all these relations are working fine!
$device = Device::where('d_id',1)->first();
$user = User::where('id',4)->first();
//dd($user,$user->deviceUser,$device,$device->deviceUser);//here instance objects and their relations can be fetched easily
$device_user = DeviceUser::where('du_device_id',1)->where('du_uid',4)->first();
//dd($device_user,$device_user->device);
//$session = Session::where('id',100)->first();//can get session by ID
$session = Session::where('s_device_id',1)->where('s_user_number','000-999')->first();//get session by unique composite key which what you are after. It is similar to the sql Query that you built. Then you can easily fetch the relations as follows:
dd($session,$session->device,$session->device->deviceUser);
Run Code Online (Sandbox Code Playgroud)
希望这会有所帮助!