如何使用 laravel 关系在 laravel 中的 3 个表之间建立关系?
How to make relation between 3 tables in laravel using laravel relation?
我有三个table:
SET NAMES utf8;
SET time_zone = '+00:00';
DROP TABLE IF EXISTS `api_credentials`;
CREATE TABLE `api_credentials` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) unsigned NOT NULL,
`api_provider_id` bigint(20) unsigned NOT NULL,
`access` text COLLATE utf8_unicode_ci,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `api_credentials_user_id_foreign` (`user_id`),
KEY `api_credentials_api_provider_id_index` (`api_provider_id`),
CONSTRAINT `api_credentials_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
CONSTRAINT `api_credentials_api_provider_id_foreign` FOREIGN KEY (`api_provider_id`) REFERENCES `api_providers` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
DROP TABLE IF EXISTS `api_providers`;
CREATE TABLE `api_providers` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` char(255) COLLATE utf8_unicode_ci NOT NULL,
`table_prefix` char(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`email_verified_at` timestamp NULL DEFAULT NULL,
`password` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`remember_token` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `users_email_unique` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
-- 2019-12-05 13:38:06
这是我的模型:
1.ApiCredential
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Pivot;
class ApiCredential extends Pivot
{
}
- Api 提供者
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ApiProvider extends Model
{
protected $fillable = [
'name',
'table_prefix'
];
public function users()
{
return $this->belongsToMany('App\Models\User')->using('App\Models\ApiCredential');
}
}
- 用户模型
namespace App\Models;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Models\ApiProvider;
use App\Models\ApiCredential;
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 apiProvider()
{
return $this->belongsToMany('App\Models\ApiProvider','api_providers','user_id','api_provider_id');
}
public function hasCredentials(String $apiProvider)
{
return $this->apiProvider()->where('name', $apiProvider)->get();
}
}
现在我想要什么:
我想根据 user
和 api_provider
从 api_credentials
table 获取记录。假设我在 api_providers
中有三个记录(名称是 adscane、cpalead、offertorro)。
我运行这个函数得到cpalead
的api_credential。
User::find(1)->hasCredentials('cpalead');
但它没有给出预期的结果。
谁能帮我解决这个问题。
我相信
# User model
public function apiProvider()
{
return $this->belongsToMany('App\Models\ApiProvider','api_providers','user_id','api_provider_id');
}
应该是
# User model
public function apiProvider()
{
return $this->belongsToMany('App\Models\ApiProvider','api_credentials','user_id','api_provider_id');
}
编辑 访问 api_credentials:
- 使用
hasMany
关系
# User model
public function apiCredentials()
{
return $this->hasMany('App\Models\ApiCredential')
}
# ApiProvider model
public function apiCredentials()
{
return $this->hasMany('App\Models\ApiCredential');
}
# ApiCredential model
public function user()
{
return $this->belongsTo('App\Models\User');
}
public function apiProvider()
{
return $this->belongsTo('App\Models\ApiProvider');
}
然后,我们重新定义 hasCredentials()
函数,使其工作如下:
# User model
public function hasCredentials(String $apiProvider)
{
$this->apiCredentials()->whereHas('apiProvider', function ($query) use ($apiProvider) {
$query->where('name', '=', $apiProvider);
})
->get();
}
使用数据如下所示:
$user = User::find($id);
foreach($user->hasCredentials('api_provider_name') as $apiCredential)
{
// $apiCredential->name
// $apiCredential->table_prefix
}
这样使用
namespace App\Model;
use Illuminate\Database\Eloquent\Model;
class ApiCredential extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
public function apiProvider()
{
return $this->belongsTo(ApiProvider::class);
}
}
和
namespace App\Model;
use Illuminate\Database\Eloquent\Model;
class ApiProvider extends Model
{
public function ApiCredentials()
{
return $this->hasMany(ApiCredential::class);
}
}
和
namespace App\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;
use Spatie\Activitylog\Traits\LogsActivity;
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 ApiCredentials()
{
return $this->hasMany(ApiCredential::class);
}
}
现在这样查询
User::with('apiCredentials.apiProvider',)
->where('id',1)
->whereHas('apiCredentials.apiProvider', function ($query) {
$query->where('name','cpalead' );
})->get();
我有三个table:
SET NAMES utf8;
SET time_zone = '+00:00';
DROP TABLE IF EXISTS `api_credentials`;
CREATE TABLE `api_credentials` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint(20) unsigned NOT NULL,
`api_provider_id` bigint(20) unsigned NOT NULL,
`access` text COLLATE utf8_unicode_ci,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `api_credentials_user_id_foreign` (`user_id`),
KEY `api_credentials_api_provider_id_index` (`api_provider_id`),
CONSTRAINT `api_credentials_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
CONSTRAINT `api_credentials_api_provider_id_foreign` FOREIGN KEY (`api_provider_id`) REFERENCES `api_providers` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
DROP TABLE IF EXISTS `api_providers`;
CREATE TABLE `api_providers` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` char(255) COLLATE utf8_unicode_ci NOT NULL,
`table_prefix` char(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`email_verified_at` timestamp NULL DEFAULT NULL,
`password` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`remember_token` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `users_email_unique` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
-- 2019-12-05 13:38:06
这是我的模型: 1.ApiCredential
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Pivot;
class ApiCredential extends Pivot
{
}
- Api 提供者
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ApiProvider extends Model
{
protected $fillable = [
'name',
'table_prefix'
];
public function users()
{
return $this->belongsToMany('App\Models\User')->using('App\Models\ApiCredential');
}
}
- 用户模型
namespace App\Models;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Models\ApiProvider;
use App\Models\ApiCredential;
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 apiProvider()
{
return $this->belongsToMany('App\Models\ApiProvider','api_providers','user_id','api_provider_id');
}
public function hasCredentials(String $apiProvider)
{
return $this->apiProvider()->where('name', $apiProvider)->get();
}
}
现在我想要什么:
我想根据 user
和 api_provider
从 api_credentials
table 获取记录。假设我在 api_providers
中有三个记录(名称是 adscane、cpalead、offertorro)。
我运行这个函数得到cpalead
的api_credential。
User::find(1)->hasCredentials('cpalead');
但它没有给出预期的结果。
谁能帮我解决这个问题。
我相信
# User model
public function apiProvider()
{
return $this->belongsToMany('App\Models\ApiProvider','api_providers','user_id','api_provider_id');
}
应该是
# User model
public function apiProvider()
{
return $this->belongsToMany('App\Models\ApiProvider','api_credentials','user_id','api_provider_id');
}
编辑 访问 api_credentials:
- 使用
hasMany
关系
# User model
public function apiCredentials()
{
return $this->hasMany('App\Models\ApiCredential')
}
# ApiProvider model
public function apiCredentials()
{
return $this->hasMany('App\Models\ApiCredential');
}
# ApiCredential model
public function user()
{
return $this->belongsTo('App\Models\User');
}
public function apiProvider()
{
return $this->belongsTo('App\Models\ApiProvider');
}
然后,我们重新定义 hasCredentials()
函数,使其工作如下:
# User model
public function hasCredentials(String $apiProvider)
{
$this->apiCredentials()->whereHas('apiProvider', function ($query) use ($apiProvider) {
$query->where('name', '=', $apiProvider);
})
->get();
}
使用数据如下所示:
$user = User::find($id);
foreach($user->hasCredentials('api_provider_name') as $apiCredential)
{
// $apiCredential->name
// $apiCredential->table_prefix
}
这样使用
namespace App\Model;
use Illuminate\Database\Eloquent\Model;
class ApiCredential extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
public function apiProvider()
{
return $this->belongsTo(ApiProvider::class);
}
}
和
namespace App\Model;
use Illuminate\Database\Eloquent\Model;
class ApiProvider extends Model
{
public function ApiCredentials()
{
return $this->hasMany(ApiCredential::class);
}
}
和
namespace App\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;
use Spatie\Activitylog\Traits\LogsActivity;
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 ApiCredentials()
{
return $this->hasMany(ApiCredential::class);
}
}
现在这样查询
User::with('apiCredentials.apiProvider',)
->where('id',1)
->whereHas('apiCredentials.apiProvider', function ($query) {
$query->where('name','cpalead' );
})->get();