表单关联关系
<h1>表单关联关系</h1>
<h3>一对一</h3>
<p><code>users</code>表和<code>profiles</code>表通过<code>profiles.user_id</code>字段生成一对一关联</p>
<pre><code class="language-sql">CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `profiles` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`age` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`gender` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;</code></pre>
<p>对应的数据模分别为:</p>
<pre><code class="language-php">&lt;?php
namespace App\Admin\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function profile()
{
return $this-&gt;hasOne(Profile::class);
}
}
class Profile extends Model
{
public function user()
{
return $this-&gt;belongsTo(User::class);
}
}</code></pre>
<p>对应的数据仓库为:</p>
<pre><code class="language-php">&lt;?php
namespace App\Admin\Repositories;
use Dcat\Admin\Repositories\EloquentRepository;
use User as UserModel;
class User extends \Dcat\Admin\Repositories\EloquentRepository
{
protected $eloquentClass = UserModel::class;
}</code></pre>
<p>通过下面的代码可以关联在一个form里面:
> {tip} 实例化数据仓库时需要传入关联模型定义的关联名称,相当于主动使用<code>Eloquent\Model::with</code>方法。</p>
<pre><code class="language-php">use App\Admin\Repositories\User;
// 注意这里实例化数据仓库`User`时必须传入&quot;profile&quot;,否则将无法关联&quot;profiles&quot;表数据
$form = Form::make(User::with('profile'), function (Form $form) {
$form-&gt;display('id');
$form-&gt;text('name');
$form-&gt;text('email');
$form-&gt;text('profile.age');
$form-&gt;text('profile.gender');
$form-&gt;datetime('created_at');
$form-&gt;datetime('updated_at');
});</code></pre>
<p>如果你不想使用数据仓库,也可以直接使用模型</p>
<pre><code class="language-php">use App\Admin\Models\User;
// 注意这里是直接使用模型,没有使用数据仓库
$form = Form::make(User::with('profile'), function (Form $form) {
$form-&gt;display('id');
...
});</code></pre>
<h3>一对多</h3>
<p>一对多的使用请参考文档<a href="model-form-fields.md#onemany">表单字段的使用-一对多</a></p>
<h3>多对多</h3>
<p>下面以项目内置的<code>角色管理</code>模块的<strong>角色绑定权限</strong>功能为例来演示多对多关联模型的用法</p>
<p>模型<code>Role</code></p>
<pre><code class="language-php">&lt;?php
namespace Dcat\Admin\Models;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
class Role extends Model
{
use HasDateTimeFormatter;
/**
* 定义你的关联模型.
*
* @return BelongsToMany
*/
public function permissions(): BelongsToMany
{
$pivotTable = 'admin_role_permissions'; // 中间表
$relatedModel = Permission::class; // 关联模型类名
return $this-&gt;belongsToMany($relatedModel, $pivotTable, 'role_id', 'permission_id');
}
}</code></pre>
<pre><code class="language-php">use Dcat\Admin\Models\Permission;
// 实例化数据仓库时传入 permissions,则会自动关联关联模型的数据
// 这里传入 permissions 关联权限模型的数据
$repository = Role::with(['permissions']);
return Form::make($repository, function (Form $form) {
$form-&gt;display('id', 'ID');
$form-&gt;text('slug', trans('admin.slug'))-&gt;required();
$form-&gt;text('name', trans('admin.name'))-&gt;required();
// 这里的数据会自动保存到关联模型中
$form-&gt;tree('permissions')
-&gt;nodes(function () {
return (new Permission())-&gt;allNodes();
})
-&gt;customFormat(function ($v) {
if (!$v) return [];
// 这一步非常重要,需要把数据库中查出来的二维数组转化成一维数组
return array_column($v, 'id');
});
...
});</code></pre>
<p>如果你不想使用数据仓库,也可以直接使用模型</p>
<pre><code class="language-php">use Dcat\Admin\Models\Role;
// 注意这里是直接使用模型,没有使用数据仓库
$form = Form::make(Role::with('permissions'), function (Form $form) {
$form-&gt;display('id');
...
});</code></pre>
<p>最终效果如下</p>
<p><img src="https://cdn.learnku.com/uploads/images/202004/26/38389/aeYpYDrUQP.png!large" alt="" /></p>
<h3>关联模型名称为驼峰风格</h3>
<p>如果你的关联模型名称的命名是<strong>驼峰</strong>风格,那么使用的时候需要转化为<strong>下划线</strong>风格命名</p>
<p>例如</p>
<pre><code class="language-php">class User extend Model
{
public function userProfile()
{
return ...;
}
}</code></pre>
<p>使用</p>
<pre><code class="language-php">return Form::make(User::with(['userProfile']), function (Form $form) {
...
// 注意这里必须使用下划线风格命名,否则将无法显示编辑数据
$form-&gt;text('user_profile.postcode');
$form-&gt;text('user_profile.address');
});</code></pre>