Laravel关系针对不同模型使用相同的文件表

时间:2018-11-08 14:55:16

标签: laravel eloquent relationship

我创建了一个files表来存储文件的元数据和找到该文件的本地路径。

我想将此表用于多个模型。

例如,users可以在该表中存储个人资料图片。但是companies可以将其徽标存储在此表中。所以实际上,我拥有的所有可以存储文件的模型都与此表有关系。

因此,在userscompanies中,我创建了列file_id,它引用了id表上的files。因为files表可以存储多个模型的文件,所以我不在{files表中存储user_idcompany_id

现在的问题是,如何将这种关系添加到userscompanies表中?因为据我所知,它要求files表的ID为userscompanies

我想念什么?

2 个答案:

答案 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表中可以有companiesfiles外键。

查看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\UserApp\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_idfileable_type。您不必手动将其放置

提示:始终阅读官方文档