Level 6
I solve it by adding Model::reguard();, from the post: Fillable and creat() not working as intended?
Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.
model isFillable() method doesn't work as it should be when use Laravel's factory's has method.
<?php
// app\Models\User.php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable, ModelTrait;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'name',
'email',
'password',
'created_ip',
'updated_ip'
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
public function posts()
{
return $this->hasMany(Post::class);
}
}
<?php
// app\Models\Post.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use HasFactory, ModelTrait;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'title',
];
}
<?php
// app\Models\ModelTrait.php
namespace App\Models;
use DateTimeInterface;
trait ModelTrait
{
public static function boot()
{
parent::boot();
static::creating(function ($model) {
if (!$model->timestamps) {
if ($model->isFillable('created_at')) {
$model->created_at = $model->freshTimestamp();
}
}
if ($model->isFillable('created_ip')) {
$model->created_ip = get_request_ip();
}
if ($model->isFillable('browser_info')) {
$model->browser_info = get_browser_info();
}
});
static::updating(function ($model) {
if ($model->isFillable('updated_ip')) {
$model->updated_ip = get_request_ip();
}
});
}
/**
* Prepare a date for array / JSON serialization.
*
* @param \DateTimeInterface $date
* @return string
*/
protected function serializeDate(DateTimeInterface $date)
{
return $date->format('Y-m-d H:i:s');
}
}
// app\helper.php
function get_request_ip()
{
return request()->ip();
}
function get_browser_info()
{
return request()->header('User-Agent');
}
<?php
// database\migrations\create_users_table.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->string('created_ip')->nullable();
$table->string('updated_ip')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
};
<?php
// database\migrations\create_posts_table.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->string('title');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('posts');
}
};
<?php
// database\Factories\UserFactory .php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
*/
class UserFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition()
{
return [
'name' => $this->faker->name(),
'email' => $this->faker->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => 'yIXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];
}
}
<?php
// database\Factories\PostFactory .php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Post>
*/
class PostFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition()
{
return [
'title' => $this->faker->sentence()
];
}
}
php artisan tinker$u=User::factory()->create();
$p=Post::factory()->create(['user_id'=>$u->id]);
$u=User::factory()->has(Post::factory())->create();
$u=User::factory()->hasPosts()->create();
Illuminate\Database\QueryException with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'created_ip' in 'field list' (SQL: insert into
posts(title,user_id,created_ip,browser_info,updated_at,created_at) values (Sunt vel sed dolores laborum., 6, 127.0.0.1, Symfony, 2022-08-16 04:04:43, 2022-08-16 04:04:43))'
Any ideas? Thank you!
I solve it by adding Model::reguard();, from the post: Fillable and creat() not working as intended?
Please or to participate in this conversation.