Laravel模型非强制FKMySQL

Laravel model non-mandatory FK MySQL

关于 Laravel 的简单问题。如果我在 mySQL 中有一个分层 table (分层,因为它是一个自递归 table,这意味着它的一个列引用另一个它自己的列

TABLE site_tree
INT page_id
INT parent_page_id (references site_tree.page_id)

这种关系的模型 eloquent 关系类型是什么?

问题 2:

TABLE site_tree
INT page_id NULL

FOREIGN KEY REFERENCES page.page_id NON-MANDATORY

TABLE page
INT page_id

在这种非强制关系中,site_tree 中的 page_id 可以为空,我将使用哪种 eloquent 关系类型?

如果我理解正确(我可能没有理解正确),这里是你的答案:

问题 1:

  • site_tree属于site_tree(parent关系)
  • site_tree hasMany site_tree (child关系)

所以我倾向于这样建模:

<?php
use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    public function parent()
    {
        return $this->belongsTo('Category', 'category_id');
    }

    public function children()
    {
        return $this->hasMany('Category', 'category_id');
    }
}

事实上,我实际上有一个特征,任何 tree-like 模型都可以使用,它有这些方法的更通用版本,像这样:

<?php
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

trait Tree
{
    public function parent()
    {
        return $this->belongsTo(get_called_class(), $this->getForeignKey());
    }

    public function children()
    {
        return $this->hasMany(get_called_class(), $this->getForeignKey());
    }

    public function scopeTopLevel(Builder $query)
    {
        return $query->whereNull($this->getForeignKey());
    }
}

还有一些额外方便的方法,如 isLeafgetAncestorsgetSiblingsgetDescendants

问题 2:

同样适用,但现在只是不同 table(外键字段的可空性真的不是什么大问题 假设我正确理解你的问题) 因为 Laravel 将只是 return 空资源或关系的空集合。我想说的是,通常如果你在两个 table 之间建立这种关系,你通常会强制执行这种关系,因为通常属于其他事物的任何事物都不会单独存在,但是嘿你的 use-case 是你的 use-case。这是 类:

<?php
use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    use Tree; // the tree behaviour from above

    public function products()
    {
        return $this->hasMany('Product');
    }
}

<?php
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    public function category()
    {
        return $this->belongsTo('Category');
    }
}

在这种情况下,我会强制执行 product belongsTo category 关系,但 category_id 可以是 null 以便拥有 'top level' category/categories.