Eloquent ORM is one of the most powerful and elegant features of Laravel. It provides a clean, expressive, and efficient way of interacting with the database using models instead of raw SQL queries. One of the most common tasks when working with a database is inserting new records, and Eloquent makes this process remarkably easy and intuitive. This comprehensive article explores in depth how to insert data using Eloquent, how fillable properties work, why mass assignment protection matters, and how to use different techniques such as create(), save(), relationships, factories, and more.
What Is Eloquent ORM in Laravel
Eloquent ORM stands for Object-Relational Mapping. It allows you to interact with database tables as if they were simple PHP classes. Each table corresponds to an Eloquent model, and each row corresponds to an instance of that model. Instead of writing SQL statements, you use expressive PHP syntax.
Eloquent helps in tasks such as:
- Inserting data
- Updating data
- Deleting data
- Querying data
- Working with relationships
When inserting data, Eloquent provides multiple straightforward methods that maintain consistency, security, and flexibility.
Basic Example of Inserting Data Using Eloquent
To insert a new record into the database, you can use the create() method:
Product::create([
'name' => 'Laptop',
'price' => 1200
]);
This single line of code inserts a new product into the products table.
However, for this to work, you must define a $fillable property in your model:
protected $fillable = ['name','price'];
This ensures that the mass assignment protection system allows these fields to be filled through the create() method.
Understanding Mass Assignment in Laravel
Laravel protects your application from mass assignment vulnerabilities. Mass assignment occurs when you pass an array of user inputs directly into a model’s methods, such as create() or update().
Without protection, a malicious user could manipulate form data to update restricted fields such as:
is_adminrolestatuspassworduser_id
To prevent this, Laravel limits which attributes can be mass assigned.
That is why the $fillable property exists.
The Role of the Fillable Property
The $fillable property is an array inside your model that explicitly defines which attributes can be mass assigned.
Example:
protected $fillable = ['name', 'price'];
This tells Laravel:
“These fields are safe to accept from user input.”
If a field is not listed in $fillable, Eloquent will not allow it to be inserted when using create() or update().
This prevents unauthorized fields from being manipulated.
Alternative to Fillable: The Guarded Property
Instead of specifying what is allowed, you can specify what is not allowed using $guarded.
Example:
protected $guarded = ['id'];
This means every field except id can be mass assigned.
Using $guarded = []; means:
“All fields are unguarded and allowed.”
However, this is risky unless you fully trust your input source.
Using the Create Method to Insert Data
The create() method is one of the cleanest ways to insert data.
Example:
Product::create([
'name' => 'Mouse',
'price' => 25
]);
This method:
- Creates a new instance
- Fills it with provided data
- Saves it to the database automatically
Conditions for using create():
- You must enable mass assignment using
$fillable - You must ensure the model uses the
HasFactorytrait if factories are used - You need timestamps if your table includes them
Using the Save Method to Insert Data
If you do not want to use mass assignment, you can insert data manually using the save() method.
Example:
$product = new Product;
$product->name = 'Keyboard';
$product->price = 50;
$product->save();
Here is how the process works:
- You create a new model instance
- Assign values individually
- Save the model to the database
This approach does not require $fillable because it is not using mass assignment.
Comparing Create and Save Methods
Both approaches insert data, but they differ in usage.
| Method | Requires Fillable | Automatic Saving | Best For |
|---|---|---|---|
| create() | Yes | Yes | Fast insertion of multiple fields |
| save() | No | No, must call save() | Custom logic before saving |
Use create() when you have validated form input.
Use save() when you need more control before storing data.
Using FirstOrCreate for Inserting Only If Not Exists
Laravel provides a convenient method to avoid duplicate entries.
Example:
Product::firstOrCreate(
['name' => 'Laptop'],
['price' => 1200]
);
This method:
- Looks for an existing record
- If found, returns it
- If not found, creates a new record
This is helpful when inserting unique items like categories or user roles.
Using FirstOrNew for Conditional Data Insertion
firstOrNew works similarly, but it does not save automatically.
Example:
$product = Product::firstOrNew(['name' => 'Tablet']);
$product->price = 400;
$product->save();
This is useful if you want to apply additional logic before saving.
Using UpdateOrCreate to Insert or Update Data
Sometimes you want to insert data if it does not exist or update the existing entry.
Example:
Product::updateOrCreate(
['name' => 'Monitor'],
['price' => 300]
);
If “Monitor” exists, it updates the price.
If not, it inserts a new record.
Working With Date Fields and Timestamps
By default, Laravel manages the created_at and updated_at columns.
When inserting data:
- Eloquent will automatically fill timestamps
- You do not need to provide them manually
If your table does not contain timestamps, disable them:
public $timestamps = false;
Inserting Data Using Request Validation
When inserting data from a form, always validate first.
Example:
$request->validate([
'name' => 'required|string',
'price' => 'required|numeric'
]);
Product::create($request->all());
This ensures only valid data enters the database.
Inserting Data Through Controllers
Typical controller method:
public function store(Request $request)
{
Product::create($request->only(['name', 'price']));
return response()->json(['message' => 'Product created']);
}
This aligns with RESTful API design.
Using Eloquent Relationships to Insert Data
Eloquent relationships allow inserting related data easily.
Example: A product belongs to a category.
$category->products()->create([
'name' => 'Smartphone',
'price' => 800
]);
This automatically fills the foreign key.
Inserting Many Records at Once Using CreateMany
When using relationships:
$category->products()->createMany([
['name' => 'TV', 'price' => 600],
['name' => 'Refrigerator', 'price' => 900]
]);
This is efficient for seeding data or importing bulk records.
Using Factories to Insert Fake Data
Laravel factories allow generating dummy data for testing.
Example:
Product::factory()->count(10)->create();
This automatically inserts 10 new products.
Factories are useful for:
- Testing
- Seeding databases
- Rapid prototyping
Using Seeder Classes to Insert Data
Laravel seeders allow inserting sample or production data programmatically.
Example:
public function run()
{
Product::create([
'name' => 'Washing Machine',
'price' => 700
]);
}
Then run:
php artisan db:seed
This is ideal for initializing your application.
Using Query Builder vs Eloquent For Inserting Data
Eloquent is model-based.
Query Builder is more SQL-oriented.
Example using Query Builder:
DB::table('products')->insert([
'name' => 'Camera',
'price' => 450
]);
Eloquent provides:
- Cleaner syntax
- Accessors and mutators
- Events
- Scopes
- Automatic timestamps
Thus, Eloquent is usually preferred.
Using Eloquent Events Before and After Insertion
Eloquent triggers several events:
- creating
- created
- saving
- saved
Example:
protected static function booted()
{
static::creating(function ($product) {
// Logic before insertion
});
}
This allows:
- Data modification
- Logging
- Notifications
- Preventing invalid inserts
Validation and Business Logic Before Saving Data
Sometimes you want to apply business rules.
Example:
if ($request->price < 1) {
return back()->withErrors('Price must be above 0');
}
Product::create($request->all());
This ensures data stays meaningful.
Using Mutators for Automatic Data Formatting
Mutators modify values before insertion.
Example:
public function setNameAttribute($value)
{
$this->attributes['name'] = ucfirst($value);
}
Now:
Product::create(['name' => 'laptop']);
Gets stored as:
Laptop
Handling JSON and Array Fields
If you have JSON columns:
protected $casts = [
'details' => 'array'
];
Now you can insert:
Product::create([
'name' => 'Phone',
'price' => 700,
'details' => ['color' => 'black', 'memory' => '64GB']
]);
Handling File Uploads When Inserting Records
If a product has an image:
$path = $request->file('image')->store('products');
Product::create([
'name' => $request->name,
'price' => $request->price,
'image' => $path
]);
Inserting Data with Transactions
Transactions ensure data integrity.
Example:
DB::transaction(function () {
Product::create([...]);
Inventory::create([...]);
});
If anything fails, nothing gets inserted.
Preventing Duplicate Inserts
You can use:
firstOrCreateupdateOrCreate- validation rules like
unique:products,name
Example validation:
'name' => 'required|unique:products'
Handling Slugs or Auto-Generated Fields
You can automatically insert slugs.
protected static function booted()
{
static::creating(function ($product) {
$product->slug = Str::slug($product->name);
});
}
Using Accessors to Format Output After Insertion
You can format data after saving using accessors.
Example:
public function getPriceFormattedAttribute()
{
return '$' . number_format($this->price, 2);
}
Soft Deletes and Their Role in Insertion
Soft deleting does not affect inserting, but it affects uniqueness checks.
A record may appear “deleted” but actually exists.
Enable soft deletes:
use SoftDeletes;
Common Mistakes When Inserting Data Using Eloquent
Developers often make mistakes such as:
- Forgetting to add
$fillable - Incorrect table or column names
- Using unvalidated data
- Forgetting timestamps
- Misusing guarded arrays
- Not handling file uploads properly
- Inserting data without checking duplicates
- Using wrong relationship methods
Understanding these helps avoid bugs.
Performance Considerations When Inserting Data
To improve performance:
- Use
insert()for bulk insertion - Minimize events and observers
- Batch process large imports
- Disable timestamps when unnecessary
Example:
DB::table('products')->insert([...]);
Logging and Monitoring Inserts
You can track insert operations using:
- Eloquent events
- Logs
- Database triggers
Example:
Log::info('Product inserted', ['id' => $product->id]);
Real-World Use Cases for Eloquent Inserts
Eloquent inserts are used in scenarios like:
- Creating user accounts
- Recording orders
- Adding blog posts
- Logging payments
- Managing inventory
- Integrating APIs
- Creating product catalogs
Leave a Reply