【问题标题】:Laravel, best way to do the relationLaravel,建立关系的最佳方式
【发布时间】:2019-07-09 13:18:26
【问题描述】:

我有这个问题:一些用户 (user_id) 可以访问报告 (report_id),但任何报告只能在有限的时间内(以天,days_count 为单位)访问,但每个报告只能访问一定数量的尝试( report_count) 在 days_count 期间。

在一张表中,逻辑是这样的:

One Table
---------
id - user_id - report_id - report_count - days_count
1 - 5 - 1 - 5 - 7
2 - 5 - 2 - 3 - 7
3 - 3 - 1 - 4 - 10

第一行将被读作:“user_id 为 5 的用户,有权访问 report_id 1,他还有 5 次访问权限,还有 7 天的访问权限” 等等

我正在考虑制作 2 个这样的表:

Table 1
---------
id - user_id - report_id - report_count
1 - 5 - 1 - 5
2 - 5 - 2 - 3
3 - 3 - 1 - 4

Table 2
---------
id - user_id - days_count
1 - 5 - 7
2 - 2 - 10

使用 2 个表的逻辑,我如何使用 Laravel 关系来建立我的关系?

【问题讨论】:

  • 在我看来,days_count 应该替换为包含用户无法访问报告的日期时间的日期时间列。如果没有created_at 列(或类似列),您当前的数据库设计将无法工作,因为days_count 不会每天更新自己。 -- 最好的设计可能是您的单表设计(我建议的更改)以及另一个记录用户访问报告的表(即用户何时访问哪个报告),因为它为您提供了最多的信息和允许您非常轻松地计算状态。

标签: sql laravel


【解决方案1】:

对于这样的事情,您可以在UserReport 之间使用BelongsToMany 关系,其中示例中的第一个表是数据透视表。

我还建议将days_count 更改为时间戳,因为这样您就不需要在每天的开始/结束时更新days_count(假设您正在这样做)。


然后,获取用户有权访问的报告如下所示:

$reports = $user->reports()
    ->whereDate('access_until', '>=', now())
    ->where('report_count', '>=', 1)
    ->get();

【讨论】:

  • 您在时间戳上是对的。在前面,管理员将输入一个input 的天数,但表格必须是时间戳。
  • 您可以简单地计算管理员输入天数时的时间戳,例如now()->addDays($request->input('days')).
【解决方案2】:

您可以将 belongsToMany relation 与其他数据透视字段一起使用。
你的用户模型应该有这样的报告关系方法:

/**
 * User belongs to many (many-to-many) Reports.
 *
 * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
 */
public function reports()
{
    // belongsToMany(RelatedModel, pivotTable, thisKeyOnPivot = report_id, otherKeyOnPivot = user_id)
    return $this->belongsToMany(Report::class)->withPivot('report_count', 'days_count');
}

报告模型将具有以下对应项

/**
 * Report belongs to many (many-to-many) Users.
 *
 * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
 */
public function users()
{
    // belongsToMany(RelatedModel, pivotTable, thisKeyOnPivot = user_id, otherKeyOnPivot = report_id)
    return $this->belongsToMany(User::class)->withPivot('report_count', 'days_count');
}

【讨论】:

  • withPivot('report_count', 'days_count') 这些是我的示例表 1 和表 2?耶稣,这两个答案都对我有很大帮助。
  • 这是您的第一个示例“一个表”中的附加字段
  • 嗯,我明白了。所以我必须只使用一个表(“一个表”),一个数据透视表,没有我在示例中放置的那个“id”字段。然后我可以访问与您的关系答案,并获得其他答案中提到的罗斯威尔逊用户的报告。
  • 没错。您将只有数据透视表。您可以通过$report->pivot->report_count; 访问数据透视数据或通过$user->reports()->wherePivot('report_count', 1); 查询它们
猜你喜欢
  • 2021-11-02
  • 2017-09-22
  • 1970-01-01
  • 1970-01-01
  • 2013-12-04
  • 1970-01-01
  • 1970-01-01
  • 2018-11-05
  • 1970-01-01
相关资源
最近更新 更多