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: