Relationships

One on one

The users table and the posts table above are related on a one-to-one basis through the posts.author_id field, and the users and post tables are structured as follows:

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

The model is defined as:

  1. class User extends Model
  2. {
  3. }
  4. class Post extends Model
  5. {
  6. public function author()
  7. {
  8. return $this->belongsTo(User::class, 'author_id');
  9. }
  10. }

A repository is defined as:

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

Then you can display the details of the user to which post belongs in the following way:

  1. use App\Models\User;
  2. $show->author(function ($model) {
  3. return Show::make($model->author_id, new User(), function (Show $show) {
  4. $show->resource('/users');
  5. $show->id();
  6. $show->name();
  7. $show->email();
  8. });
  9. });

{tip} In order to be able to use the tools in the upper right corner of this panel properly, the resource method must be used to set the url access path to the user resource.

If there are other conditional queries required for your associative model, you can refer to the following

  1. use App\Models\User;
  2. $show->author(function ($model) {
  3. // Model setting query conditions
  4. $userModel = User::where('state', $model->state);
  5. return Show::make($model->author_id, $userModel, function (Show $show) {
  6. // Setting Up Routes
  7. $show->resource('/users');
  8. $show->id();
  9. $show->name();
  10. $show->email();
  11. });
  12. });

Easy way

If you’re simply displaying information from an associated table, you could also write it like this

  1. // If you're using a model, you can specify an association like this
  2. $model = Post::with('author');
  3. // If you're using a repository, you can specify the relationships like this
  4. // $repository = new Post(['author']);
  5. return Show::make($id, $model, function (Show $show) {
  6. $show->field('author.id', 'Author ID');
  7. $show->field('author.name', 'Author name');
  8. ...
  9. });

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

  1. // Note that this must be named with an underscore style, otherwise the edit data will not be displayed.
  2. $show->field('user_profile.postcode');
  3. $show->field('user_profile.address');

One-to-many

One-to-many will be presented as a data table, here is a simple example

The posts table and the comment table comments are in a one-to-many relationship (a post has multiple comments), which is associated by the comments.post_id field.

  1. CREATE TABLE `comments` (
  2. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  3. `post_id` int(10) unsigned NOT NULL,
  4. `content` 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

The model is defined as:

  1. class Post extends Model
  2. {
  3. public function comments()
  4. {
  5. return $this->hasMany(Comment::class);
  6. }
  7. }
  8. class Comment extends Model
  9. {
  10. }

A repository is defined as:

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

Then the display of comments is made possible by the following code:

  1. use App\Admin\Repositories\Comment;
  2. $show->comments(function ($model) {
  3. $grid = new Grid(new Comment);
  4. $grid->model()->where('post_id', $model->id);
  5. // Setting Up Routes
  6. $grid->resource('comments');
  7. $grid->id();
  8. $grid->content()->limit(10);
  9. $grid->created_at();
  10. $grid->updated_at();
  11. $grid->filter(function ($filter) {
  12. $filter->like('content')->width('300px');
  13. });
  14. return $grid;
  15. });

Note: The resource() method must be used to set the url to the comments resource in order to use this datagrid functionality properly!

Many-to-many

Many-to-many will be presented as a data table, here is a simple example

The role table roles and the permission table permissions are in a many-to-many relationship and are related via the middle table role_permissions

  1. CREATE TABLE `roles` (
  2. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  3. `name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
  4. `slug` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
  5. `created_at` timestamp NULL DEFAULT NULL,
  6. `updated_at` timestamp NULL DEFAULT NULL,
  7. PRIMARY KEY (`id`),
  8. UNIQUE KEY `admin_roles_name_unique` (`name`)
  9. ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  10. CREATE TABLE `permissions` (
  11. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  12. `name` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
  13. `slug` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
  14. `http_method` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  15. `http_path` text COLLATE utf8mb4_unicode_ci,
  16. `order` int(11) NOT NULL DEFAULT '0',
  17. `parent_id` int(11) NOT NULL DEFAULT '0',
  18. `created_at` timestamp NULL DEFAULT NULL,
  19. `updated_at` timestamp NULL DEFAULT NULL,
  20. PRIMARY KEY (`id`),
  21. UNIQUE KEY `admin_permissions_name_unique` (`name`)
  22. ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
  23. CREATE TABLE `role_permissions` (
  24. `role_id` int(11) NOT NULL,
  25. `permission_id` int(11) NOT NULL,
  26. `created_at` timestamp NULL DEFAULT NULL,
  27. `updated_at` timestamp NULL DEFAULT NULL,
  28. KEY `admin_role_permissions_role_id_permission_id_index` (`role_id`,`permission_id`)
  29. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

The model is defined as:

  1. class Role extends Model
  2. {
  3. public function permissions() : BelongsToMany
  4. {
  5. return $this->belongsToMany(Permission::class, 'role_permissions', 'role_id', 'permission_id');
  6. }
  7. }
  8. class Permission extends Model
  9. {
  10. }

A repository is defined as:

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

Then the permissions are displayed using the following code:

  1. use App\Admin\Repositories\Permission;
  2. $show->permissions(function ($model) {
  3. $grid = new Grid(new Permission);
  4. $grid->model()->join('role_permissions', function ($join) use ($model) {
  5. $join->on('role_permissions.permission_id', 'id')
  6. ->where('role_id', '=', $model->id);
  7. });
  8. // Setting Up Routes
  9. $grid->resource('auth/permissions');
  10. $grid->id;
  11. $grid->name;
  12. $grid->slug;
  13. $grid->http_path;
  14. $grid->filter(function (Grid\Filter $filter) {
  15. $filter->equal('id')->width('300px');
  16. });
  17. return $grid;
  18. });