php - 如何在 Laravel 中使用两个 foreignId

标签 php database laravel

我有两个表:

用户:

Schema::create('users', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->string('loginid')->unique();
        $table->string('password');
        $table->rememberToken();
        $table->timestamps();
    });

知识产权:

Schema::create('i_p_s', function (Blueprint $table) {
        $table->id();
        $table->string('address')->unique();

        $table->foreignId('user_id')->nullable();
        $table->string('hostname');
        $table->string('description')->nullable();
        $table->timestamps();

        $table->index('user_id');
    });

知识产权模型:

public function User() {
    return $this->belongsTo(User::class);
}

用户模型:

public function IPs() {
    return $this->hasMany(IP::class);
}

user_id 列表示该 IP 被哪个用户使用。

现在我想添加一个新列last_modified,这意味着谁是这一行的最后一个编辑者。

所以我认为 last_modified 也应该是 $table->foreignId('user_id')->nullable();

但是如何定义IP模型中的关系呢?

另外,我现在这样调用user_id

$ips = IP::with('user')->get();

@foreach ($ips as $ip)
    {{ $ip->user }}
@endforeach

那么如何在定义之后调用last_modified呢?

非常感谢

最佳答案

如文档 ( https://laravel.com/docs/7.x/migrations#foreign-key-constraints ) 中所示,

$table->foreignId('user_id')->nullable();

只是“老”方式的捷径

Schema::table('i_p_s', function (Blueprint $table) {
    $table->unsignedBigInteger('user_id');

    $table->foreign('user_id')->references('id')->on('users');
});

您的代码的问题在于,您还需要 constrained() 方法。它会将给定的列名(如 user_id)分解为 “Laravel,请在此处使用表 users 的列 id.
我不确定 nullable() 方法是否可用于此快捷方式。

以同样的方式,您的关系将在您的模型中消失。如果你没有向 belongsTo()haveMany() 方法添加额外的值,Laravel 将尝试通过假定标准命名约定来遍历你的数据库主键和表名(如果表名未在您的模型中设置)。

  • primary keys are assumed as id. This is also the reason why $table->ip() works.
  • table names are assumed as the plural of the model name. That means also, you have to make sure to set the name of your i_p_s table within your IP-model as it does not follow the convention. Event better would be to think about an adaption to the convention and call your table ips.
  • foreign keys should be (to be able to dissolve things that way) named by the singular table name, underscore, primary key. in other words user_id.

因此,除了不能添加名为 user_id 的第二列这一事实之外,您的假设应该是正确的。对于您的第二个外键,您的代码应该看起来像执行此操作的“正常/传统”方式。

Schema::table('i_p_s', function (Blueprint $table) {
    $table->unsignedBigInteger('last_modified')->nullable();

    $table->foreign('last_modified')->references('id')->on('users');
});

我很确定这会起作用,尽管我还没有测试过。不幸的是,我不确定您是否可以在约束方法中也提供列名和表。如果是这样,那将非常方便。试一试,否则使用传统方式。

模型中的关系应该如下所示:

public function hasChanged() {
    $this->hasMany(IP::class, 'last_modified', 'id');
}

last_modified is the foreign key within the i_p_s-table while id is the local column of your owning User-model.

将其转化为 IP 模型:

public function wasChangedBy() {
    $this->belongsTo(User::class, 'last_modified', 'id');
}

In both cases you can dispense on setting the 'id' column as primary key of your users-table as it is standard.

由于构造/架构,关系与示例中的相同。在 99% 中,这始终是一对多关系。

最后但同样重要的是,看到同一个外键的这种构造在同一个表中引用两次,有点奇怪。但是我找到了这篇文章,上面说这样做最终是完全正常的。
Mysql: using two foreign keys to the same table

我能想到的唯一其他方法是在 i_p_susers 之间有一个中间表,但这会导致这两个表之间的数据库循环这也是你应该避免的事情。所以我会说这没问题。

希望这有帮助;)

关于php - 如何在 Laravel 中使用两个 foreignId,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61110810/

相关文章:

php - laravel 编辑 phpunit.xml 以在测试时更改环境

php 按最新的顺序列出目录文件

javascript - 为 php 中的特定 get 请求执行 javascript

MySQL:如何在多对多关系的两个表之间创建映射

php - PDOException SQLSTATE[HY000] [2002] 没有这样的文件或目录

php - Laravel 5.3 更改密码

php - Laravel Form PUT 方法不起作用

PHP函数每次将变量递增1

c# - 需要参数 '@ID' ,但未提供?

php - 如何使用eloquent根据表列和hasMany关系的计数返回记录