Laravel Mass Assignment Foreign Key Definition

class Model implements ArrayAccess, Arrayable, Jsonable, JsonSerializable, QueueableEntity, UrlRoutable (View source)

Constants

CREATED_AT

The name of the "created at" column.

UPDATED_AT

The name of the "updated at" column.

Properties

protected string $connectionThe connection name for the model.
protected string $tableThe table associated with the model.
protected string $primaryKeyThe primary key for the model.
protected string $keyTypeThe "type" of the auto-incrementing ID.
protected int $perPageThe number of models to return for pagination.
bool $incrementingIndicates if the IDs are auto-incrementing.
bool $timestampsIndicates if the model should be timestamped.
protected array $attributesThe model's attributes.
protected array $originalThe model attribute's original state.
protected array $relationsThe loaded relationships for the model.
protected array $hiddenThe attributes that should be hidden for arrays.
protected array $visibleThe attributes that should be visible in arrays.
protected array $appendsThe accessors to append to the model's array form.
protected array $fillableThe attributes that are mass assignable.
protected array $guardedThe attributes that aren't mass assignable.
protected array $datesThe attributes that should be mutated to dates.
protected string $dateFormatThe storage format of the model's date columns.
protected array $castsThe attributes that should be cast to native types.
protected array $touchesThe relationships that should be touched on save.
protected array $observablesUser exposed observable events.
protected array $withThe relations to eager load on every query.
protected string $morphClassThe class name to be used in polymorphic relations.
bool $existsIndicates if the model exists.
bool $wasRecentlyCreatedIndicates if the model was inserted during the current request lifecycle.
static bool $snakeAttributesIndicates whether attributes are snake cased on arrays.
static protected ConnectionResolverInterface$resolverThe connection resolver instance.
static protected Dispatcher$dispatcherThe event dispatcher instance.
static protected array $bootedThe array of booted models.
static protected array $globalScopesThe array of global scopes on the model.
static protected bool $unguardedIndicates if all mass assignment is enabled.
static protected array $mutatorCacheThe cache of the mutated attributes for each class.
static array $manyMethodsThe many to many relationship methods.

Methods

void

__construct(array $attributes = [])

Create a new Eloquent model instance.

void

static void

boot()

The "booting" method of the model.

static void

bootTraits()

Boot all of the bootable traits on the model.

static void

static void

observe(object|string $class, int $priority)

Register an observer with the Model.

fill(array $attributes)

Fill the model with an array of attributes.

forceFill(array $attributes)

Fill the model with an array of attributes. Force mass assignment.

array

Model

newInstance(array $attributes = [], bool $exists = false)

Create a new instance of the given model.

Model

newFromBuilder(array $attributes = [], string|null $connection = null)

Create a new model instance that is existing.

static Collection

hydrate(array $items, string|null $connection = null)

Create a collection of models from plain arrays.

static Collection

hydrateRaw(string $query, array $bindings = [], string|null $connection = null)

Create a collection of models from a raw query.

static Model

create(array $attributes = [])

Save a new model and return the instance.

static Model

forceCreate(array $attributes)

Save a new model and return the instance. Allow mass-assignment.

static Builder

on(string|null $connection = null)

Begin querying the model on a given connection.

static Collection|Model[]

all(array|mixed $columns = ['*'])

Get all of the models from the database.

|null

fresh(array|string $with = [])

Reload a fresh model instance from the database.

load(array|string $relations)

Eager load relations on the model.

static Builder|Model

with(array|string $relations)

Begin querying a model with eager loading.

append(array|string $attributes)

Append attributes to query when building a query.

HasOne

hasOne(string $related, string $foreignKey = null, string $localKey = null)

Define a one-to-one relationship.

MorphOne

morphOne(string $related, string $name, string $type = null, string $id = null, string $localKey = null)

Define a polymorphic one-to-one relationship.

BelongsTo

belongsTo(string $related, string $foreignKey = null, string $otherKey = null, string $relation = null)

Define an inverse one-to-one or many relationship.

MorphTo

morphTo(string $name = null, string $type = null, string $id = null)

Define a polymorphic, inverse one-to-one or many relationship.

HasMany

hasMany(string $related, string $foreignKey = null, string $localKey = null)

Define a one-to-many relationship.

HasManyThrough

hasManyThrough(string $related, string $through, string|null $firstKey = null, string|null $secondKey = null, string|null $localKey = null)

Define a has-many-through relationship.

MorphMany

morphMany(string $related, string $name, string $type = null, string $id = null, string $localKey = null)

Define a polymorphic one-to-many relationship.

BelongsToMany

belongsToMany(string $related, string $table = null, string $foreignKey = null, string $otherKey = null, string $relation = null)

Define a many-to-many relationship.

MorphToMany

morphToMany(string $related, string $name, string $table = null, string $foreignKey = null, string $otherKey = null, bool $inverse = false)

Define a polymorphic many-to-many relationship.

MorphToMany

morphedByMany(string $related, string $name, string $table = null, string $foreignKey = null, string $otherKey = null)

Define a polymorphic, inverse many-to-many relationship.

string

joiningTable(string $related)

Get the joining table name for a many-to-many relation.

static int

destroy(array|int $ids)

Destroy the models for the given IDs.

bool|null

delete()

Delete the model from the database.

bool|null

forceDelete()

Force a hard delete on a soft deleted model.

static void

saving(Closure|string $callback, int $priority)

Register a saving model event with the dispatcher.

static void

saved(Closure|string $callback, int $priority)

Register a saved model event with the dispatcher.

static void

updating(Closure|string $callback, int $priority)

Register an updating model event with the dispatcher.

static void

updated(Closure|string $callback, int $priority)

Register an updated model event with the dispatcher.

static void

creating(Closure|string $callback, int $priority)

Register a creating model event with the dispatcher.

static void

created(Closure|string $callback, int $priority)

Register a created model event with the dispatcher.

static void

deleting(Closure|string $callback, int $priority)

Register a deleting model event with the dispatcher.

static void

deleted(Closure|string $callback, int $priority)

Register a deleted model event with the dispatcher.

static void

int

increment(string $column, int $amount = 1, array $extra = [])

Increment a column's value by a given amount.

int

decrement(string $column, int $amount = 1, array $extra = [])

Decrement a column's value by a given amount.

int

incrementOrDecrement(string $column, int $amount, array $extra, string $method)

Run the increment or decrement method on the model.

bool|int

update(array $attributes = [], array $options = [])

Update the model in the database.

bool

push()

Save the model and all of its relationships.

bool

save(array $options = [])

Save the model to the database.

bool

saveOrFail(array $options = [])

Save the model to the database using transaction.

void

finishSave(array $options)

Finish processing on a successful save operation.

void

insertAndSetId(Builder $query, array $attributes)

Insert the given attributes and set the ID on the model.

void

bool

touches(string $relation)

Determine if the model touches a given relation.

mixed

fireModelEvent(string $event, bool $halt = true)

Fire the given event for the model.

bool

touch()

Update the model's update timestamp.

setCreatedAt(mixed $value)

Set the value of the "created at" attribute.

setUpdatedAt(mixed $value)

Set the value of the "updated at" attribute.

Pivot

newPivot(Model $parent, array $attributes, string $table, bool $exists)

Create a new pivot model instance.

string

getTable()

Get the table associated with the model.

setTable(string $table)

Set the table associated with the model.

mixed

getKey()

Get the value of the model's primary key.

string

setKeyName(string $key)

Set the primary key for the model.

mixed

array

getMorphs(string $name, string $type, string $id)

Get the polymorphic relationship columns.

string

int

getPerPage()

Get the number of models to return per page.

setPerPage(int $perPage)

Set the number of models to return per page.

string

array

getHidden()

Get the hidden attributes for the model.

setHidden(array $hidden)

Set the hidden attributes for the model.

void

addHidden(array|string|null $attributes = null)

Add hidden attributes for the model.

makeVisible(array|string $attributes)

Make the given, typically hidden, attributes visible.

makeHidden(array|string $attributes)

Make the given, typically visible, attributes hidden.

withHidden(array|string $attributes) deprecated

Make the given, typically hidden, attributes visible.

array

getVisible()

Get the visible attributes for the model.

setVisible(array $visible)

Set the visible attributes for the model.

void

addVisible(array|string|null $attributes = null)

Add visible attributes for the model.

setAppends(array $appends)

Set the accessors to append to model arrays.

array

getFillable()

Get the fillable attributes for the model.

fillable(array $fillable)

Set the fillable attributes for the model.

array

getGuarded()

Get the guarded attributes for the model.

guard(array $guarded)

Set the guarded attributes for the model.

static void

unguard(bool $state = true)

Disable all mass assignable restrictions.

static void

reguard()

Enable the mass assignment restrictions.

static bool

isUnguarded()

Determine if current state is "unguarded".

static mixed

unguarded(callable $callback)

Run the given callable while being unguarded.

bool

isFillable(string $key)

Determine if the given attribute may be mass assigned.

bool

isGuarded(string $key)

Determine if the given key is guarded.

bool

getIncrementing()

Get the value indicating whether the IDs are incrementing.

string

toJson(int $options)

Convert the model instance to JSON.

array

jsonSerialize()

Convert the object into something JSON serializable.

array

toArray()

Convert the model instance to an array.

array

mixed

bool

hasGetMutator(string $key)

Determine if a get mutator exists for an attribute.

mixed

mutateAttribute(string $key, mixed $value)

Get the value of an attribute using its mutator.

mixed

mutateAttributeForArray(string $key, mixed $value)

Get the value of an attribute using its mutator for array conversion.

bool

hasCast(string $key, array|string|null $types = null)

Determine whether an attribute should be cast to a native type.

bool

isDateCastable(string $key)

Determine whether a value is Date / DateTime castable for inbound manipulation.

bool

isJsonCastable(string $key)

Determine whether a value is JSON castable for inbound manipulation.

string

getCastType(string $key)

Get the type of cast for a model attribute.

mixed

castAttribute(string $key, mixed $value)

Cast an attribute to a native PHP type.

setAttribute(string $key, mixed $value)

Set a given attribute on the model.

bool

hasSetMutator(string $key)

Determine if a set mutator exists for an attribute.

array

getDates()

Get the attributes that should be converted to dates.

Carbon

asDateTime(mixed $value)

Return a timestamp as DateTime object.

int

asTimeStamp(mixed $value)

Return a timestamp as unix timestamp.

setDateFormat(string $format)

Set the date format used by the model.

string

asJson(mixed $value)

Encode the given value as JSON.

mixed

fromJson(string $value, bool $asObject = false)

Decode the given JSON back into an array or object.

Model

replicate(array $except = null)

Clone the model into a new, non-existing instance.

array

Eloquent ORM

Contents

The Basics

An ORM is an object-relational mapper, and Laravel has one that you will absolutely love to use. It is named "Eloquent" because it allows you to work with your database objects and relationships using an eloquent and expressive syntax. In general, you will define one Eloquent model for each table in your database. To get started, let's define a simple model:

class User extends Eloquent {}

Nice! Notice that our model extends the Eloquent class. This class will provide all of the functionality you need to start working eloquently with your database.

Note: Typically, Eloquent models live in the application/models directory.

Conventions

Eloquent makes a few basic assumptions about your database structure:

  • Each table should have a primary key named id.
  • Each table name should be the plural form of its corresponding model name.

Sometimes you may wish to use a table name other than the plural form of your model, or a different primary key column. No problem. Just add a static table property your model:

class User extends Eloquent { public static $table = 'my_users'; public static $key = 'my_primary_key'; }

Retrieving Models

Retrieving models using Eloquent is refreshingly simple. The most basic way to retrieve an Eloquent model is the static find method. This method will return a single model by primary key with properties corresponding to each column on the table:

$user = User::find(1); echo $user->email;

The find method will execute a query that looks something like this:

SELECT * FROM "users" WHERE "id" = 1

Need to retrieve an entire table? Just use the static all method:

$users = User::all(); foreach ($users as $user) { echo $user->email; }

Of course, retrieving an entire table isn't very helpful. Thankfully, every method that is available through the fluent query builder is available in Eloquent. Just begin querying your model with a static call to one of the query builder methods, and execute the query using the get or first method. The get method will return an array of models, while the first method will return a single model:

$user = User::where('email', '=', $email)->first(); $user = User::where_email($email)->first(); $users = User::where_in('id', array(1, 2, 3))->or_where('email', '=', $email)->get(); $users = User::order_by('votes', 'desc')->take(10)->get();

Note: If no results are found, the first method will return NULL. The all and get methods return an empty array.

Aggregates

Need to get a MIN, MAX, AVG, SUM, or COUNT value? Just pass the column to the appropriate method:

$min = User::min('id'); $max = User::max('id'); $avg = User::avg('id'); $sum = User::sum('id'); $count = User::count();

Of course, you may wish to limit the query using a WHERE clause first:

$count = User::where('id', '>', 10)->count();

Inserting & Updating Models

Inserting Eloquent models into your tables couldn't be easier. First, instantiate a new model. Second, set its properties. Third, call the save method:

$user = new User; $user->email = 'example@gmail.com'; $user->password = 'secret'; $user->save();

Alternatively, you may use the create method, which will insert a new record into the database and return the model instance for the newly inserted record, or false if the insert failed.

$user = User::create(array('email' => 'example@gmail.com'));

Updating models is just as simple. Instead of instantiating a new model, retrieve one from your database. Then, set its properties and save:

$user = User::find(1); $user->email = 'new_email@gmail.com'; $user->password = 'new_secret'; $user->save();

Need to maintain creation and update timestamps on your database records? With Eloquent, you don't have to worry about it. Just add a static timestamps property to your model:

class User extends Eloquent { public static $timestamps = true; }

Next, add created_at and updated_at date columns to your table. Now, whenever you save the model, the creation and update timestamps will be set automatically. You're welcome.

In some cases it may be useful to update the updated_at date column without actually modifying any data within the model. Simply use the touch method, which will also automatically save the changes immediately:

$comment = Comment::find(1); $comment->touch();

You can also use the timestamp function to update the updated_at date column without saving the model immediately. Note that if you are actually modifying the model's data this is handled behind the scenes:

$comment = Comment::find(1); $comment->timestamp(); //do something else here, but not modifying the $comment model data $comment->save();

Note: You can change the default timezone of your application in the application/config/application.php file.

Relationships

Unless you're doing it wrong, your database tables are probably related to one another. For instance, an order may belong to a user. Or, a post may have many comments. Eloquent makes defining relationships and retrieving related models simple and intuitive. Laravel supports three types of relationships:

To define a relationship on an Eloquent model, you simply create a method that returns the result of either the has_one, has_many, belongs_to, or has_many_and_belongs_to method. Let's examine each one in detail.

One-To-One

A one-to-one relationship is the most basic form of relationship. For example, let's pretend a user has one phone. Simply describe this relationship to Eloquent:

Notice that the name of the related model is passed to the has_one method. You can now retrieve the phone of a user through the phone method:

$phone = User::find(1)->phone()->first();

Let's examine the SQL performed by this statement. Two queries will be performed: one to retrieve the user and one to retrieve the user's phone:

SELECT * FROM "users" WHERE "id" = 1 SELECT * FROM "phones" WHERE "user_id" = 1

Note that Eloquent assumes the foreign key of the relationship will be user_id. Most foreign keys will follow this model_id convention; however, if you want to use a different column name as the foreign key, just pass it in the second parameter to the method:

Want to just retrieve the user's phone without calling the first method? No problem. Just use the dynamic phone property. Eloquent will automatically load the relationship for you, and is even smart enough to know whether to call the get (for one-to-many relationships) or first (for one-to-one relationships) method:

$phone = User::find(1)->phone;

What if you need to retrieve a phone's user? Since the foreign key (user_id) is on the phones table, we should describe this relationship using the belongs_to method. It makes sense, right? Phones belong to users. When using the belongs_to method, the name of the relationship method should correspond to the foreign key (sans the _id). Since the foreign key is user_id, your relationship method should be named user:

Great! You can now access a User model through a Phone model using either your relationship method or dynamic property:

echo Phone::find(1)->user()->first()->email; echo Phone::find(1)->user->email;

One-To-Many

Assume a blog post has many comments. It's easy to define this relationship using the has_many method:

Now, simply access the post comments through the relationship method or dynamic property:

$comments = Post::find(1)->comments()->get(); $comments = Post::find(1)->comments;

Both of these statements will execute the following SQL:

SELECT * FROM "posts" WHERE "id" = 1 SELECT * FROM "comments" WHERE "post_id" = 1

Want to join on a different foreign key? No problem. Just pass it in the second parameter to the method:

You may be wondering: If the dynamic properties return the relationship and require less keystrokes, why would I ever use the relationship methods? Actually, relationship methods are very powerful. They allow you to continue to chain query methods before retrieving the relationship. Check this out:

echo Post::find(1)->comments()->order_by('votes', 'desc')->take(10)->get();

Many-To-Many

Many-to-many relationships are the most complicated of the three relationships. But don't worry, you can do this. For example, assume a User has many Roles, but a Role can also belong to many Users. Three database tables must be created to accomplish this relationship: a users table, a roles table, and a role_user table. The structure for each table looks like this:

users:

id - INTEGER email - VARCHAR

roles:

id - INTEGER name - VARCHAR

role_user:

id - INTEGER user_id - INTEGER role_id - INTEGER

Tables contain many records and are consequently plural. Pivot tables used in has_many_and_belongs_to relationships are named by combining the singular names of the two related models arranged alphabetically and concatenating them with an underscore.

Now you're ready to define the relationship on your models using the has_many_and_belongs_to method:

Great! Now it's time to retrieve a user's roles:

$roles = User::find(1)->roles()->get();

Or, as usual, you may retrieve the relationship through the dynamic roles property:

$roles = User::find(1)->roles;

If your table names don't follow conventions, simply pass the table name in the second parameter to the has_many_and_belongs_to method:

By default only certain fields from the pivot table will be returned (the two id fields, and the timestamps). If your pivot table contains additional columns, you can fetch them too by using the with() method :

Inserting Related Models

Let's assume you have a Post model that has many comments. Often you may want to insert a new comment for a given post. Instead of manually setting the post_id foreign key on your model, you may insert the new comment from it's owning Post model. Here's what it looks like:

$comment = new Comment(array('message' => 'A new comment.')); $post = Post::find(1); $comment = $post->comments()->insert($comment);

When inserting related models through their parent model, the foreign key will automatically be set. So, in this case, the "post_id" was automatically set to "1" on the newly inserted comment.

When working with relationships, you may use the method to insert / update related models:

$comments = array( array('message' => 'A new comment.'), array('message' => 'A second comment.'), ); $post = Post::find(1); $post->comments()->save($comments);

Inserting Related Models (Many-To-Many)

This is even more helpful when working with many-to-many relationships. For example, consider a User model that has many roles. Likewise, the Role model may have many users. So, the intermediate table for this relationship has "user_id" and "role_id" columns. Now, let's insert a new Role for a User:

$role = new Role(array('title' => 'Admin')); $user = User::find(1); $role = $user->roles()->insert($role);

Now, when the Role is inserted, not only is the Role inserted into the "roles" table, but a record in the intermediate table is also inserted for you. It couldn't be easier!

However, you may often only want to insert a new record into the intermediate table. For example, perhaps the role you wish to attach to the user already exists. Just use the attach method:

$user->roles()->attach($role_id);

It's also possible to attach data for fields in the intermediate table (pivot table), to do this add a second array variable to the attach command containing the data you want to attach:

$user->roles()->attach($role_id, array('expires' => $expires));

Alternatively, you can use the method, which accepts an array of IDs to "sync" with the intermediate table. After this operation is complete, only the IDs in the array will be on the intermediate table.

$user->roles()->sync(array(1, 2, 3));

Working With Intermediate Tables

As your probably know, many-to-many relationships require the presence of an intermediate table. Eloquent makes it a breeze to maintain this table. For example, let's assume we have a User model that has many roles. And, likewise, a Role model that has many users. So the intermediate table has "user_id" and "role_id" columns. We can access the pivot table for the relationship like so:

$user = User::find(1); $pivot = $user->roles()->pivot();

Once we have an instance of the pivot table, we can use it just like any other Eloquent model:

foreach ($user->roles()->pivot()->get() as $row) { // }

You may also access the specific intermediate table row associated with a given record. For example:

$user = User::find(1); foreach ($user->roles as $role) { echo $role->pivot->created_at; }

Notice that each related Role model we retrieved is automatically assigned a pivot attribute. This attribute contains a model representing the intermediate table record associated with that related model.

Sometimes you may wish to remove all of the record from the intermediate table for a given model relationship. For instance, perhaps you want to remove all of the assigned roles from a user. Here's how to do it:

$user = User::find(1); $user->roles()->delete();

Note that this does not delete the roles from the "roles" table, but only removes the records from the intermediate table which associated the roles with the given user.

Eager Loading

Eager loading exists to alleviate the N + 1 query problem. Exactly what is this problem? Well, pretend each Book belongs to an Author. We would describe this relationship like so:

Now, examine the following code:

foreach (Book::all() as $book) { echo $book->author->name; }

How many queries will be executed? Well, one query will be executed to retrieve all of the books from the table. However, another query will be required for each book to retrieve the author. To display the author name for 25 books would require 26 queries. See how the queries can add up fast?

Thankfully, you can eager load the author models using the with method. Simply mention the function name of the relationship you wish to eager load:

foreach (Book::with('author')->get() as $book) { echo $book->author->name; }

In this example, only two queries will be executed!

SELECT * FROM "books" SELECT * FROM "authors" WHERE "id" IN (1, 2, 3, 4, 5, …)

Obviously, wise use of eager loading can dramatically increase the performance of your application. In the example above, eager loading cut the execution time in half.

Need to eager load more than one relationship? It's easy:

$books = Book::with(array('author', 'publisher'))->get();

Note: When eager loading, the call to the static with method must always be at the beginning of the query.

You may even eager load nested relationships. For example, let's assume our Author model has a "contacts" relationship. We can eager load both of the relationships from our Book model like so:

$books = Book::with(array('author', 'author.contacts'))->get();

If you find yourself eager loading the same models often, you may want to use $includes in the model.

$includes takes the same arguments that with takes. The following is now eagerly loaded.

foreach (Book::all() as $book) { echo $book->author->name; }

Note: Using with will override a models $includes.

Constraining Eager Loads

Sometimes you may wish to eager load a relationship, but also specify a condition for the eager load. It's simple. Here's what it looks like:

$users = User::with(array('posts' => function($query) { $query->where('title', 'like', '%first%'); }))->get();

In this example, we're eager loading the posts for the users, but only if the post's "title" column contains the word "first".

Getter & Setter Methods

Setters allow you to handle attribute assignment with custom methods. Define a setter by appending "set_" to the intended attribute's name.

Call a setter method as a variable (without parenthesis) using the name of the method without the "set_" prefix.

Getters are very similar. They can be used to modify attributes before they're returned. Define a getter by appending "get_" to the intended attribute's name.

Call the getter method as a variable (without parenthesis) using the name of the method without the "get_" prefix.

Mass-Assignment

Mass-assignment is the practice of passing an associative array to a model method which then fills the model's attributes with the values from the array. Mass-assignment can be done by passing an array to the model's constructor:

$user = new User(array( 'username' => 'first last', 'password' => 'disgaea' )); $user->save();

Or, mass-assignment may be accomplished using the fill method.

$user = new User; $user->fill(array( 'username' => 'first last', 'password' => 'disgaea' )); $user->save();

By default, all attribute key/value pairs will be stored during mass-assignment. However, it is possible to create a white-list of attributes that will be set. If the accessible attribute white-list is set then no attributes other than those specified will be set during mass-assignment.

You can specify accessible attributes by assigning the $accessible static array. Each element contains the name of a white-listed attribute.

public static $accessible = array('email', 'password', 'name');

Alternatively, you may use the accessible method from your model:

User::accessible(array('email', 'password', 'name'));

Note: Utmost caution should be taken when mass-assigning using user-input. Technical oversights could cause serious security vulnerabilities.

Converting Models To Arrays

When building JSON APIs, you will often need to convert your models to array so they can be easily serialized. It's really simple.

Convert a model to an array:

return json_encode($user->to_array());

The method will automatically grab all of the attributes on your model, as well as any loaded relationships.

Sometimes you may wish to limit the attributes that are included in your model's array, such as passwords. To do this, add a attribute definition to your model:

Excluding attributes from the array:

class User extends Eloquent { public static $hidden = array('password'); }

Deleting Models

Because Eloquent inherits all the features and methods of Fluent queries, deleting models is a snap:

$author->delete();

Note, however, than this won't delete any related models (e.g. all the author's Book models will still exist), unless you have set up foreign keys and cascading deletes.

0 thoughts on “Laravel Mass Assignment Foreign Key Definition

Leave a Reply

Your email address will not be published. Required fields are marked *