Relationships
#Relationship Types
Laraform can handle Eloquent relationships out of the box. In this chapter we're going through the different types of relationships that assigned models can have, as well as the different element types they can be used with.
#HasOne
HasOne
type of relationships typically represent an Object type elements. Having an attribute with a HasOne
relationship will save the related object as a separate entity.
Table Structure
Let's assumne we have the following tables:
users
id - integer
email - string
profiles
id - integer
user_id - integer
name - string
bio - string
Model Structure
The User
has a profile
attribute defined as a hasOne
relationship type in its model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public $fillable = ['email'];
public function profile() {
return $this->hasOne(Profile::class);
}
}
Form Structure
The following form will save the profile
object to profiles
table and will automatically associate with the user:
<?php
namespace App\Forms;
class UserForm extends \Laraform
{
public $model = \App\User::class;
public function schema() {
return [
'id' => [
'type' => 'key'
],
'email' => [
'type' => 'text',
'label' => 'Email'
],
'profile' => [
'type' => 'object',
'schema' => [
'name' => [
'type' => 'text',
'label' => 'Name'
],
'bio' => [
'type' => 'textarea',
'label' => 'Bio'
]
]
]
];
}
}
Compatible Elements
The following elements are designed to be used with hasOne
relationship type:
#HasMany
HasMany
type relationships are usually associated with List type elements and they can store multiple related entities.
Table Structure
Let's assume our user can have multiple phones and their type
and number
need to be stored:
users
id - integer
phones
id - integer
user_id - integer
type - string
number - string
Model Structure
The User
model has the phones
attribute defined as a hasMany
relationship:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function phones() {
return $this->hasMany(Phone::class);
}
}
Form Structure
The following form will store its phones
object list in the phones
table:
<?php
namespace App\Forms;
class UserForm extends \Laraform
{
public $model = \App\User::class;
public function schema() {
return [
'id' => [
'type' => 'key'
],
'phones' => [
'type' => 'list',
'label' => 'Phones',
'object' => [
'schema' => [
'type' => [
'type' => 'text',
'placeholder' => 'Type'
],
'number' => [
'type' => 'textarea',
'placeholder' => 'Number'
]
]
]
]
];
}
}
Compatible Elements
The following elements are designed to be used with hasMany
relationship type:
#BelongsToMany
BelongsToMany
relationships are used to assign entities of two database tables as a many-to-many relationship.
Table Structure
Let's see an example where the user can be associated with different roles:
users
id - integer
roles
id - integer
name - string
role_user
id - integer
user_id - integer
role_id - integer
Model Structure
The User
model has the roles
attribute defined as a belongsToMany
relationship:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function roles() {
return $this->belongsToMany(Role::class);
}
}
Form Structure
Assuming we have 3 roles stored in the roles
table 1 - Admin
, 2 - Editor
, 3 - User
, the following form will store the user's roles in the role_user
table:
<?php
namespace App\Forms;
class UserForm extends \Laraform
{
public $model = \App\User::class;
public function schema() {
return [
'id' => [
'type' => 'key'
],
'roles' => [
'type' => 'checkboxgroup',
'label' => 'Roles',
'items' => [
1 => 'Admin',
2 => 'Editor',
3 => 'User'
]
],
];
}
}
Compatible Elements
The following elements are designed to be used with belongsToMany
relationship type:
#BelongsTo
On a form level belongsTo
type of relationship is really just a simple field that contains an ID associated with a relationship's ID from another table.
Table Structure
Let's see an example where we have the following tables:
tasks
id - integer
user_id - integer
name - string
description - string
users
id - integer
Model Structure
The Task
model belongs to exactly one User
:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Task extends Model
{
public function user() {
return $this->belongsTo(User::class);
}
}
Form Structure
The form has a user_id
select which will directly assign the task to a user.
<?php
namespace App\Forms;
class TaskForm extends \Laraform
{
public $model = \App\Task::class;
public function schema() {
return [
'id' => [
'type' => 'key'
],
'name' => [
'type' => 'text',
'label' => 'Name'
],
'description' => [
'type' => 'textarea',
'label' => 'Description'
],
'user_id' => [
'type' => 'select',
'label' => 'Assigned user',
'items' => $this->userItems()
]
];
}
protected function userItems() {
return \App\User::all()->mapWithKeys(function ($user) {
return [$user->id => $user->name];
});
}
}
Compatible Elements
The following elements are designed to be used with belongsTo
relationship type:
#MorphMany
MorphMany
relationships are used when you have a certain type of entity (eg. photo) that can be associated with different type of models (eg. photo of a user, photo of a post).
Table Structure
Let's see an example where we have the following tables:
users
id - integer
posts
id - integer
photos
id - integer
photo - string
photoable_id - integer
photoable_type - integer
Model Structure
The User
model is associated with the photos
using a morphMany
relationship, while the Photo
model has a photoable
property which defines that it is being morphed to something:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
public function photos() {
return $this->morphMany(Photo::class, 'photoable');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Photo extends Model
{
public $fillable = ['photo'];
public function photoable() {
return $this->morphTo();
}
}
Form Structure
Given the models above the following form will save the user's photos to the photos
table and associate them with the user's ID and App\User
photoable_type
:
<?php
namespace App\Forms;
class UserForm extends \Laraform
{
public $model = \App\User::class;
public function schema() {
return [
'id' => [
'type' => 'key'
],
'photos' => [
'type' => 'gallery',
'label' => 'Photos',
// This is the name of the `photo` column
// in the `photos` table where the actual
// url of the photo will be stored.
//
// Learn more at: /uploading-files
'storeFile' => 'photo'
]
];
}
}
Compatible Elements
The following elements are designed to be used with morphMany
relationship type:
#MorphToMany
MorphToMany
relationships are often used when entities of a certain database table can be assigned to different type of models.
Table Structure
Let's see an example where we have a common tags
table and tags can be assigned to posts
and videos
via taggables
table:
posts
id - integer
name - string
videos
id - integer
name - string
tags
id - integer
name - string
taggables
tag_id - integer
taggable_id - integer
taggable_type - string
Model Structure
Here we have the model of Post
where tags
is defined as a morphToMany
relationship:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function tags() {
return $this->morphToMany(Tag::class, 'taggable');
}
}
Form Structure
Assuming we have to tags stored in the tags
table 1 - php
, 2 - javascript
, the following form willl automatically save its tags to taggables
table using the post's id
as taggable_id
and App\Post
as taggable_type
:
<?php
namespace App\Forms;
class PostForm extends \Laraform
{
public $model = \App\Post::class;
public function schema() {
return [
'tags' => [
'type' => 'tags',
'label' => 'Tags',
'items' => [
1 => 'php',
2 => 'javascript'
]
],
];
]
}
Compatible Elements
The following elements are designed to be used with morphToMany
relationship type:
#MorphTo
The belongsTo
relationship type can be a simple field that contains an ID associated with a relationship's ID from another table.
Table Structure
Let's see an example where we have the following table:
images
id - integer
url - string
imageable_id - integer
imageable_type - string
Model Structure
The Image
model has imagable
with morphTo()
:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Image extends Model
{
public function imageable()
{
return $this->morphTo();
}
}
Form Structure
The form has imageable_type
and imageable_id
free text inputs.
<?php
namespace App\Forms;
class ImageForm extends \Laraform
{
public $model = \App\Image::class;
public function schema() {
return [
'id' => [
'type' => 'key'
],
'url' => [
'type' => 'text',
'label' => 'URL'
],
'imageable_type' => [
'type' => 'text',
'label' => 'Owner type'
],
'imageable_id' => [
'type' => 'text',
'label' => 'Owner ID'
]
];
}
}
Compatible Elements
The following elements are designed to be used with morphTo
relationship type: