我正在尝试使用模型工厂来播种数据库,但是在运行它时出现错误:
Trying to get property 'id' of non-object
这是我的代码:
// TasksTableSeeder.php
factory(pams\Task::class, '2000', rand(1, 30))->create();
// ModelFactory.php
$factory->defineAs(pams\Task::class, '2000', function (Faker\Generator $faker) {
static $task_number = 01;
return [
'task_number' => $task_number++,
'ata_code' => '52-00-00',
'time_estimate' => $faker->randomFloat($nbMaxDecimals = 2, $min = 0.25, $max = 50),
'work_order_id' => '2000',
'description' => $faker->text($maxNbChars = 75),
'action' => '',
'duplicate' => '0',
'certified_by' => '1',
'certified_date' => '2015-11-08',
'status' => '1',
'created_by' => '1',
'modified_by' => '1',
'created_at' => Carbon\Carbon::now()->format('Y-m-d H:i:s'),
'updated_at' => Carbon\Carbon::now()->format('Y-m-d H:i:s'),
];
});
我尝试从模型工厂中删除所有变量并使用常量,但这并不能解决问题。我曾尝试从ModelFactory.php
中提取数据并将其直接放入TasksTableSeeder.php
中,并且确实可以使用,但是我使用的是常量,没有变量。
我无法终生弄清楚它在说什么'id'。
我正在运行Laravel v5.1
答案 0 :(得分:3)
您的BaseModel
并不完全合适,因为它会迫使您创建黑客来运行诸如单元测试之类的东西。最好在BaseModel
中有一个标志,然后在设置created_by
和modified_by
之前测试是否为真。
除非在创建user_id
之前先在工厂中实际创建User
,否则我们无法保证在任何时间点都将Task
设为'1'。
一种解决当前设置的方法是设置一个受保护的字段,例如$enableAuthUpdates
,默认情况下将其设置为false或true。然后,您可以覆盖任何派生模型(例如任务模型)中的字段,以阻止创建/更新事件运行。
同样重要的是要确保您的工厂有一个正在使用的实际用户,并在不存在的情况下创建它。
答案 1 :(得分:2)
我发现了问题。在一个阶段,我实现了一个BaseModel.php
模型,该模型在创建或更新模型时会自动插入当前用户ID。播种器失败,因为没有当前用户,所以我必须添加检查以查看是否有首先登录的用户。
代码如下:
static::creating(function($model)
{
if(Auth::user())
{
$model->created_by = Auth::user()->id;
$model->modified_by = Auth::user()->id;
}
else
{
$model->created_by = '1';
$model->modified_by = '1';
}
});
static::updating(function($model)
{
if(Auth::user())
{
$model->modified_by = Auth::user()->id;
}
else
{
$model->modified_by = '1';
}
});
它不是很漂亮,但是可以完成工作:)