我创建了一个files
表来存储文件的元数据和找到该文件的本地路径。
我想将此表用于多个模型。
例如,users
可以在该表中存储个人资料图片。但是companies
可以将其徽标存储在此表中。所以实际上,我拥有的所有可以存储文件的模型都与此表有关系。
因此,在users
和companies
中,我创建了列file_id
,它引用了id
表上的files
。因为files
表可以存储多个模型的文件,所以我不在{files表中存储user_id
或company_id
。
现在的问题是,如何将这种关系添加到users
和companies
表中?因为据我所知,它要求files
表的ID为users
或companies
。
我想念什么?
答案 0 :(得分:1)
这似乎是Polymorphic Relationship。从文档中:
多态关系
表结构
多态关系允许一个模型在单个关联上属于一个以上的模型。例如, 想象您的应用程序的用户可以同时在帖子和 视频。使用多态关系,您可以使用单个
comments
这两个方案的表格。首先,让我们检查一下桌子 建立这种关系所需的结构:posts id - integer title - string body - text videos id - integer title - string url - string comments id - integer body - text commentable_id - integer commentable_type - string
需要注意的两个重要列是
commentable_id
和commentable_type
表上的comments
列。commentable_id
列将包含帖子或视频的ID值,而commentable_type
列将包含所属类的名称 模型。commentable_type
列是ORM如何确定 访问commentable
时要返回的拥有模型的“类型” 关系。模型结构
接下来,让我们检查建立这种关系所需的模型定义:
use Illuminate\Database\Eloquent\Model; class Comment extends Model { /** * Get all of the owning commentable models. */ public function commentable() { return $this->morphTo(); } } class Post extends Model { /** * Get all of the post's comments. */ public function comments() { return $this->morphMany('App\Comment', 'commentable'); } } class Video extends Model { /** * Get all of the video's comments. */ public function comments() { return $this->morphMany('App\Comment', 'commentable'); } }
因此,在您的情况下,文件表结构可能如下所示:
files
id - integer
url - string
fileable_id - integer // <--- the id of the object
fileable_type - string // <-- the type of the object (user, company, etc)
然后在您的模型中:
File.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class File extends Model
{
/**
* Get all of the owning fileable models.
*/
public function fileable()
{
return $this->morphTo();
}
}
User.php
class User extends Model
{
/**
* Get all of the user's files.
*/
public function files()
{
return $this->morphMany(File::class, 'fileable');
// or
// return $this->morphOne(File::class, 'fileable'); equivalent to hasOne
}
}
Company.php
class Company extends Model
{
/**
* Get all of the company's files.
*/
public function files()
{
return $this->morphMany(File::class, 'fileable');
// or
// return $this->morphOne(File::class, 'fileable'); equivalent to hasOne
}
}
答案 1 :(得分:1)
您的方向正确。
您的users
表中可以有companies
和files
外键。
查看Laravel 5多态关系。
https://laravel.com/docs/5.7/eloquent-relationships#polymorphic-relations
您可以拥有外键fileable_id
和外键fileable_type
的类型
如果要为companies
记录添加文件
假设您的公司ID为24,使用的型号为App\Models\Company
将以下内容添加到文件模型App\File
public function fileableable()
{
return $this->morphTo();
}
然后关注您的App\User
和App\Company
public function files()
{
return $this->morphMany('App\Comment', 'fileable'); // use morphOne if you want One to One relation
}
要为公司创建文件。
$company = Company::find(24);
$company->files()->create([
'path' => '/folder/myfile.txt',
'size' => '14585',
'extension' => 'txt',
]);
在此阶段,您可能会得到MassAssignmentException
在您的App\File
模型中
添加$fillable = ['path', 'size' , 'extension'];
您的记录如下:
id path size extension fileable_id fileable_type
1 /folder/myfile.txt 14585 txt 24 App\Models\Company
Laravel根据调用关联方法的对象自动存储fileable_id
和fileable_type
。您不必手动将其放置
提示:始终阅读官方文档