0

在我的代码中,每个公司都属于一个包,并且有一个包使用类 Package extends Model。包装型号:

protected $fillable =[
    'name',
    'daily_cv_view',
    'monthly_cv_view',
    'per_job_post_cv_view',
    'active_job_post_limit',
    'question_per_job_post_limit',
    'package_lifetime',
    'job_post_lifetime_limit',
    'price'
    ];
public function companies()
{
    return $this->hasMany('App\Models\Company');
}

public function packageUsages()
{
    return $this->hasMany('App\Models\package_usage');
}

公司模式

 public function package()
    {
        return $this->belongsTo('App\Models\Package', 'package_id');
    }

包使用模型

public function company()
    {
        return $this->belongsTo('App\Models\Company');
    }
    public function package()
    {
        return $this->belongsTo('App\Models\Package');
    }

在我的数据库播种机中,我正在尝试为每个创建的公司构建一个包圣人。所以它看起来像这样:

 $companies=factory(App\Models\Company::class, 20)->create()->each(function ($company) {
            $company->users()->save(factory(App\Models\User::class)->make());
            $company->events()->save(factory(\App\Models\Event::class)->make());
        });
        foreach ($companies as $company)
            $company->packageUsages()->save(factory(\App\Models\PackageUsage::class)->make([
                'company_id'=>$company->id,
                'package_id'=>$company->first()->package_id
            ]));

最后我的 pacage 使用 fctory 像这样:

$factory->define(App\Models\PackageUsage::class, function (Faker $faker) {
    $companyId= $faker->randomElement(\App\Models\Company::all()->pluck('id')->toArray());
    $company= App\Models\Company::find($companyId);
    $package=$company->package;
    $dailyCvView=$package->first()->daily_cv_view;
    return [
        'company_id'=>$company,
        'package_id'=>$package,
        'daily_cv_view'=>$faker->numberBetween($min=0 , $max=$dailyCvView ),
        'monthly_cv_view'=>$faker->numberBetween($min=$dailyCvView , $max=$package->monthly_cv_view ),
        'active_job_post_count'=>$company->jobPosts->count(),
        'expiration_date'=>$faker->dateTimeBetween($min='now', $max='+ 30 days')
    ];
});

公司工厂:

$factory->define(\App\Models\Company::class, function (Faker $faker) {
        return [
        'name'=>$faker->company,
        'company_size'=>$faker->randomElement(['10','50','100','200']),
        'slogan'=>'باما کار کنید',
        'website'=>$faker->domainName,
        'logo'=>'/images/companies/avatar',
        'message_title'=>'ما در اینجا.....',
        'message_content'=>$faker->paragraph('10'),
        'main_photo'=>'/images/companies/mainphotos/avatar',
        'about_us'=>$faker->paragraph('10'),
        'why_us'=>$faker->paragraph('10'),
        'recruiting_steps'=>$faker->paragraph('10'),
        'address'=>$faker->address,
        'email'=>$faker->safeEmail,
        'phone_number'=>$faker->numberBetween(10,100),
        'location'=>$faker->city,
            'package_id'=>$faker->randomElement(\App\Models\Package::all()->pluck('id')->toArray())
    ];
});

当我运行它时,它返回错误:

   Illuminate\Database\QueryException  : SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`balatar`.`package_usages`, CONSTRAINT `package_usages_package_id_foreign` FOREIGN KEY (`package_id`
) REFERENCES `packages` (`id`)) (SQL: insert into `package_usages` (`company_id`, `package_id`, `daily_cv_view`, `monthly_cv_view`, `active_job_post_count`, `expiration_date`, `updated_at`, `created_at`) values (4, 4, 12, 484, 0, 2018-09-16 07:26:11, 2018-08-30
 03:45:22, 2018-08-30 03:45:22))

当我检查数据库时,我看到它为每个公司 ID 和包 ID 创建了 3 个包。因为我想第四个,当它尝试用 4 个 id 构建它并且我只插入 3 个包时,外键失败。我的代码有什么问题?

4

1 回答 1

1

我认为您的第一个错误是您的数据库设计。据我了解,您的公司将拥有不止一个软件包,因为我知道当时只有一个有效的软件包。companies所以它需要在你的和表之间创建一个多对多的关系packages,如下所示:

Schema::create('rel_company_package', function (Blueprint $table) {
    $table->increments('id');
    $table->timestamps();
    $table->unsignedInteger('package_id');
    $table->unsignedInteger('company_id');
    $table->timestamp('activated_at')->nullable();
    $table->timestamp('expires_at')->nullable();
    $table->boolean('is_active')->nullable();
    $table->unsignedInteger('nubmer_of_remaining_job_posts');
});
  1. actived_at:贵公司激活其包的日期。
  2. nubmer_of_remaining_job_posts:首先来自您的包裹数据,并且在您的公司发布职位后立即减一。
  3. expires_at:当您的包裹过期时
  4. is_active:这个字段是多余的,但会帮助你消耗更多的内存而不是计算资源。将确定当前分配的包是否处于活动状态

注意:您应该在决定激活软件包后立即填写activated_at,expires_at和正确的值。is_active

您也应该nubmer_of_remaining_job_posts在包裹分配时间填写。

您决定播种的是您可能不依赖于生产时间的日志数据,因为它很容易变得庞大并且需要大量资源来计算您想要的内容。顺便说一句,日志数据 ( PackageUsage) 应该只保留您的数据透视表 ( rel_company_package) id

让我们直接回到您的错误:

首先,在company factory你加载所有包并随机选择一个(和你package usage factory的),你最好不要这样做,而是让 MySQL 为你随机选择一个

对于随机公司:

$company = $\App\Models\Company::query()->inRandomOrder->first();
// and use $company->id

对于随机包装:

$package = \App\Models\Package::query()->inRandomOrder()->frist();
// and use $package->id

另一点是,您应该创建一个PackageUsage如下所示的实例:

$company->packageUsages()->save(factory(\App\Models\PackageUsage::class)->make([
    'package_id' => $company->first()->package_id
]));

它不需要company_id再次通过。并且您似乎错过了模型中的packageUsages()方法Company,它应该像:

public function packagesUsage() 
{
    return $this->hasMany('\App\Models\PackageUsage', 'company_id')
}

它可能是由您替换comapny_idpackage_id.

但正如我一开始提到的,你最好先修复你的结构。

于 2018-08-30T11:46:49.267 回答