【发布时间】:2021-05-09 18:12:33
【问题描述】:
我正在寻找解决我一段时间以来遇到的问题的方法。也许你可以激励我做得更好。我试图在规划过程中不犯基本错误,因此我向您征求意见。
我有一个 Contact::model,它几乎没有固定属性,如 id 等。此外,我希望为整个 Contact::model 动态创建不同的属性。某些用户将获得向整个模型添加名称、电子邮件、地址等属性的功能。我已经放弃了通过创建/删除列以编程方式更新表本身的想法(这会引入不同的问题)。至于现在我已经创建了两个额外的表。一个带有额外的列名 [Columns::model] 和一个数据透视表,用于将值分配给 Contact::model 和 Column::model。
为了列出所有联系人,我将 ContactColumn 表准备为数组,其中第一个键是contact_id,第二个是column_id,因此我得到了值。这引入了 n+1 问题。这不会那么糟糕,但是使用这种方法,通过动态列值、过滤、搜索等对联系人进行排序将非常困难(或消耗资源)。
您能否以某种方式指导我找到更好的解决方案。如何将联系人集合与给定列的值合并,使其看起来像一个固定表?
<table>
<thead>
<tr>
<th>Fixed columns [i.e. ID]</th>
@foreach ($columns as $column)
<th>{{ $column->name }}</th>
@endforeach
</tr>
</thead>
<tbody>
@foreach ($contacts as $contact)
<tr>
<td>{{ $contact->id }}</td>
@foreach ($columns as $column)
<td>
@if (array_key_exists($column->id, $values[$contact->id]))
{{ $values[$contact->id][$column->id] }}
@endif
</td>
@endforeach
</tr>
@endforeach
</tbody>
</table>
还有$value 数组。
foreach (ColumnContact::all() as $pivot) {
$values[$pivot->contact_id][$pivot->column_id] = $pivot->value;
}
return $values;
编辑:我已经这样解决了
$this->contacts = Contact::when($this->dynamicColumnName, function($query) {
$query->join('column_contact', function ($join) {
$join->on('id', '=', 'column_contact.contact_id')
->where('column_contact.column_id', '=', $this->dynamicColumnName->id);
})
->orderBy('value', $this->orderingDirection);
})
(...)
->paginate(self::PER_PAGE);
【问题讨论】:
-
您是否考虑过只添加一个包含自定义用户数据的 json 列?
-
我不确定这是否能解决我的排序和过滤问题,并且一个单元格中的数据可能会变得非常大。
-
您可以按laravel.com/docs/8.x/queries#json-where-clauses 中所述的 JSON 查询进行排序或过滤,至于大小我认为 MySQL 的 JSON 列可以大到 2GB。您还可以使用 JSON 列创建虚拟辅助字段和索引,如 dev.mysql.com/doc/refman/5.7/en/… 中所述
-
您好,谢谢您的回答。我对 JSON 查询的阅读和研究越多,我就越想对此进行测试,我认为这可能是解决方案。谢谢你。另外我被告知:github.com/spatie/laravel-schemaless-attributes