【问题标题】:Laravel Factory Deeply Nested Relationships FailureLaravel 工厂深度嵌套关系失败
【发布时间】:2021-03-08 12:30:51
【问题描述】:

我遇到了一个问题,即具有深度嵌套关系的工厂无法从 DB 外键错误中正确执行。

我有一系列工厂用于通过应用模型将数据传播到数据库中。当我运行所有基础级别(没有关系的工厂)工厂时,我没有任何问题。当我运行所有单级工厂(具有单一关系的工厂)时,我没有任何问题。但是,当我运行任何二级工厂(与另一个工厂有关系的工厂与另一个工厂有关系)时,我会收到数据库错误。

简单来说,这意味着我可以毫无问题地自行运行ProductKeyFactoryActivationCodeFactory。这只发生在我尝试运行FeatureActivationFactory

我的工厂

class FeatureActivationFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = FeatureActivation::class;

    /** @var string $connection DB Connection */
    protected $connection = License::DB;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'code_id' => ActivationCode::factory(),
            'productSoftware_id' => ProductSoftware::factory(),
            'date' => now()
        ];
    }
}

class ActivationCodeFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = ActivationCode::class;

    /** @var string $connection DB Connection */
    protected $connection = License::DB;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'key_id' => ProductKey::factory(),
            'code' => $this->faker->lexify('??????????'),
            'isActive' => 0
        ];
    }
}

class ProductKeyFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = ProductKey::class;

    /** @var string $connection DB Connection */
    protected $connection = License::DB;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'name' => $this->faker->unique->word,
            'startDate' => now(),
            'endDate' => $this->faker->dateTimeThisYear()
        ];
    }
}

我的工厂错误FeatureActivation::factory()->create();:

删除了不正确的错误消息。

编辑

感谢大家指出我的愚蠢错误。是的,这是由于名称重复而导致的错误,但这不是我最终得到的错误。感谢您指出 unique 功能 - 我添加了该功能以避免该错误。请参阅下面的正确错误消息:

Illuminate/Database/QueryException with message 'SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`license`.`activationCodes`, CONSTRAINT `FK_ActivationCodes_KeyID` FOREIGN KEY (`key_id`) REFERENCES `activationCodes` (`id`) ON DELETE RESTRICT) (SQL: insert into `activationCodes` (`key_id`, `code`, `isActive`) values (18, zvszgdrrlj, 0))'

【问题讨论】:

  • 您是否在致电您的工厂之前刷新您的数据库,并且只致电您的工厂一次?错误很明显,您已经有一个带有 name="December" 的条目,并且您已经使用唯一索引定义了该列。
  • @miken32 我错误地复制了错误消息,但您指出这一点是正确的 - 我添加了唯一方法并将随机字符串更改为另一种方法。

标签: laravel eloquent factory


【解决方案1】:

如果你必须处理唯一索引,你需要告诉 Faker 避免生成相同的月份名称。

class ProductKeyFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = ProductKey::class;

    /** @var string $connection DB Connection */
    protected $connection = License::DB;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'name' => $this->faker->unique()->monthName,
            'startDate' => now(),
            'endDate' => $this->faker->dateTimeThisYear()
        ];
    }
}

【讨论】:

  • 感谢您指出这一点 - 我不知道 faker 库的独特功能。我错误地复制了错误的错误,因此唯一键错误是一个问题,但不是最终问题。
【解决方案2】:

这是由于我的错误。嵌套关系确实有效,但是,测试模型中声明的任何内容以确保它们正常工作非常重要 - 特别是在使用更复杂的关系时,例如 hasOnThrough 等,尤其是与不遵循 laravel 的列结合使用时/雄辩的命名约定。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-01
    • 1970-01-01
    • 2016-06-25
    • 1970-01-01
    • 1970-01-01
    • 2021-03-11
    • 2020-08-01
    相关资源
    最近更新 更多