Feedback Stay at home and get up to 40% off with STAYATHOME coupon code | 0d 0h 0m 0s left

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: