Form Relationships

One-on-one

users table and profiles table generate one-to-one associations via the profiles.user_id field

  1. CREATE TABLE `users` (
  2. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  3. `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  4. `email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  5. `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  6. `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  7. PRIMARY KEY (`id`)
  8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
  9. CREATE TABLE `profiles` (
  10. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  11. `user_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  12. `age` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  13. `gender` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  14. `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  15. `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  16. PRIMARY KEY (`id`)
  17. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

The corresponding models are:

  1. <?php
  2. namespace App\Admin\Models;
  3. use Illuminate\Database\Eloquent\Model;
  4. class User extends Model
  5. {
  6. public function profile()
  7. {
  8. return $this->hasOne(Profile::class);
  9. }
  10. }
  11. class Profile extends Model
  12. {
  13. public function user()
  14. {
  15. return $this->belongsTo(User::class);
  16. }
  17. }

The corresponding repository is:

  1. <?php
  2. namespace App\Admin\Repositories;
  3. use Dcat\Admin\Repositories\EloquentRepository;
  4. use User as UserModel;
  5. class User extends \Dcat\Admin\Repositories\EloquentRepository
  6. {
  7. protected $eloquentClass = UserModel::class;
  8. }

The following code can be associated with a form:

{tip} Instantiating the repository requires passing in the association name defined by the association model, which is equivalent to actively using the Eloquent\Model::with method.

  1. use App\Admin\Repositories\User;
  2. // Note that the repository `User` must be instantiated with `profile` here, otherwise the `profiles` table data will not be associated.
  3. $form = Form::make(User::with('profile'), function (Form $form) {
  4. $form->display('id');
  5. $form->text('name');
  6. $form->text('email');
  7. $form->text('profile.age');
  8. $form->text('profile.gender');
  9. $form->datetime('created_at');
  10. $form->datetime('updated_at');
  11. });

If you don’t want to use a repository, you can simply use the model

  1. use App\Admin\Models\User;
  2. // Note that the model is used directly here, not the repository
  3. $form = Form::make(User::with('profile'), function (Form $form) {
  4. $form->display('id');
  5. ...
  6. });

One-to-many

For the use of one-to-many, please refer to the documentation Use of Form Fields - One-to-Many.

Many-to-many

The following is an example of the Role Bind Permissions function of the built-in Role Management module to demonstrate the Usages of many-to-many association models.

Model Role

  1. <?php
  2. namespace Dcat\Admin\Models;
  3. use Dcat\Admin\Traits\HasDateTimeFormatter;
  4. use Illuminate\Database\Eloquent\Model;
  5. use Illuminate\Database\Eloquent\Relations\BelongsToMany;
  6. class Role extends Model
  7. {
  8. use HasDateTimeFormatter;
  9. /**
  10. * 定义你的关联模型.
  11. *
  12. * @return BelongsToMany
  13. */
  14. public function permissions(): BelongsToMany
  15. {
  16. $pivotTable = 'admin_role_permissions'; // intermediate table
  17. $relatedModel = Permission::class; // Related model class name
  18. return $this->belongsToMany($relatedModel, $pivotTable, 'role_id', 'permission_id');
  19. }
  20. }
  1. use Dcat\Admin\Models\Permission;
  2. // Passing permissions when instantiating a repository automatically associates the data of the related model.
  3. // Here we pass in data for permissions associated with the permission model.
  4. $repository = Role::with(['permissions']);
  5. return Form::make($repository, function (Form $form) {
  6. $form->display('id', 'ID');
  7. $form->text('slug', trans('admin.slug'))->required();
  8. $form->text('name', trans('admin.name'))->required();
  9. // The data here is automatically saved in the associated model.
  10. $form->tree('permissions')
  11. ->nodes(function () {
  12. return (new Permission())->allNodes();
  13. })
  14. ->customFormat(function ($v) {
  15. if (!$v) return [];
  16. // This is a very important step to convert the two-dimensional array found in the database into a one-dimensional array
  17. return array_column($v, 'id');
  18. });
  19. ...
  20. });

If you don’t want to use a repository, you can simply use the model

  1. use Dcat\Admin\Models\Role;
  2. // Note that the model is used directly here, not the repository.
  3. $form = Form::make(Role::with('permissions'), function (Form $form) {
  4. $form->display('id');
  5. ...
  6. });

The final result is as follows

Form Relationships - 图1

Associated model name is camelCase style

If the name of your associated model is named camelCase style, then the use needs to be converted to snakecase style naming

for example

  1. class User extend Model
  2. {
  3. public function userProfile()
  4. {
  5. return ...;
  6. }
  7. }

use

  1. return Form::make(User::with(['userProfile']), function (Form $form) {
  2. ...
  3. // Note that you must use snake_case style naming here, otherwise the edited data will not be displayed.
  4. $form->text('user_profile.postcode');
  5. $form->text('user_profile.address');
  6. });