【问题标题】:Laravel relationship through an array of JSON objectsLaravel 通过 JSON 对象数组建立关系
【发布时间】:2020-05-16 11:16:50
【问题描述】:

型号:

用户 hasMany ,并且hasMany 角色 通过

有很多用户

这些关系被存储在 group 表中名为“members”的列中,其格式如下:

[
    {
        user_id: *user_id_one*
        role_id: *role_id_one*
    },
    {
        user_id: *user_id_two*
        role_id: *role_id_two*
    },
]

要求:

  • 模型必须通过关系链接,以便我可以急切地加载它们。
  • 我无法更改数据结构,因为已经对这些模型和结构进行了大量编程。
  • 必须使用 5.7 的 sql 版本完成
  • 必须使用 php 7.1、7.2 或 7.3 完成

我试过了:

我首先在 User 模型中尝试了这个:

method:
$this->hasMany('\App\Group', 'members->[*].user_id')

query:
select * from `groups` where json_unquote(json_extract(`groups`.`members`, '$."[*].user_id"')) = ? and json_unquote(json_extract(`groups`.`members`, '$."[*].user_id"')) is not null

然后:

method:
$this->hasMany('\App\Group', 'members->[*].user_id')
or
$this->hasMany('\App\Group', 'members->$[*].user_id')

query:
Column Not Found

强大的staudenmeir/eloquent-json-relations让我更接近

method:
$this->hasManyJson('\App\Group', 'members->[*].user_id')

query:
select * from `groups` where json_contains(`groups`.`members`, ?, '$."[*].user_id"')


这些都尝试了正常的主键和返回的自定义属性:
  • “JSON_ARRAY(primary_key)”
  • “JSON_OBJECT('id',primary_key)”
  • "['primary_key']"
  • "{'id': 'primary_key'}"

但是这些都用引号转义了。


已经考虑过:

这是一个工作属性的示例

public function getGroupsAttribute()
{
    return Group::whereRaw("JSON_CONTAINS(members->'$[*].user_id', JSON_ARRAY('{$this->id}'))")->get();
}

在我离开并建立自定义关系之前,我想我会在这里问。我可能可以在范围内做一些事情来应用类似以下的内容(使用刚刚返回所有组的关系),但这将是相同的工作量并且不太干净。

->with(['groups' => function ($query) use ($user) {
   $query->whereRaw("JSON_CONTAINS(members->'$[*].user_id', JSON_ARRAY('{$user->id}'))")
}])

【问题讨论】:

  • 出于演示目的,我更改了伪随机选择的成员列的值。假设该列是有效的 JSON。
  • “我无法更改数据结构...”提示 David Tennant in the rain 的表情包,说“对不起。我非常非常抱歉。”
  • 基于 JSON 字段的外键引用示例是我演示文稿How to Use JSON in MySQL Wrong 的主要部分。
  • @BillKarwin Ik 伙计,如果由我决定,我会制作一个数据透视表 (ノ﹏ヽ)

标签: php mysql json laravel eloquent


【解决方案1】:

使用eloquent-json-relations 包,您可以像这样实现groups 关系:

class User extends Model
{
    use \Staudenmeir\EloquentJsonRelations\HasJsonRelationships;

    public function groups()
    {
       return $this->hasManyJson(Group::class, 'members[]->user_id');
    }
}

class Group extends Model
{
    use \Staudenmeir\EloquentJsonRelations\HasJsonRelationships;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-14
    • 2018-02-15
    • 1970-01-01
    • 2018-05-20
    • 2016-12-20
    • 1970-01-01
    相关资源
    最近更新 更多