简体   繁体   English

在Laravel 5.2中使用工厂关系违反完整性约束

[英]Integrity constraint violation using factory relationships in laravel 5.2

I am new to testing in laravel and I'm trying to create dummy data using Model Factories. 我是在laravel中进行测试的新手,我正在尝试使用模型工厂创建虚拟数据。 I have three tables: 我有三个表:

  • firms 商行
  • clients 客户
  • briefs 内裤

A firm has many clients and a client has many briefs. 一个公司有很多客户,一个客户有很多简介。 The format of clients and briefs is very similar. clientsbriefs的格式非常相似。 They both have foreign keys firm_id and client_id respectfully. 它们都分别具有外键firm_idclient_id Whilst doing a phpunit test I want to create an instance of a client from a firm and an instance of a brief from the client using the following code: 在进行phpunit测试的同时,我想使用以下代码创建一个公司的客户实例和一个客户的摘要实例:

$client = $firm->clients()
               ->save(factory(App\SearchFirmClient::class)->create());
$brief  = $client->briefs()
                 ->save(factory(App\SearchFirmBrief::class)->create());

$client is created without a fuss but $brief throws up an error: $client创建时没有大惊小怪,但是$brief引发错误:

Illuminate\Database\QueryException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'client_id' cannot be null (SQL: insert into `search_firms_briefs` (`user_id`, `title`, `description`, `contact_id`, `client_id`, `updated_at`, `created_at`) values (1, Et in amet., Quo soluta ut impedit nesciunt autem. Laborum aperiam est non molestiae animi non quod. Explicabo eligendi doloribus ex quia vitae placeat ut., 0, , 2016-03-30 10:06:34, 2016-03-30 10:06:34))

The formats of both tables: 这两个表的格式:

Schema::create('search_firms_clients', function(Blueprint $table)
{
    $table->increments('client_id');
    $table->integer('search_firm_id')->unsigned();
    $table->foreign('search_firm_id')->references('id')->on('search_firms')->onDelete('cascade');           
    $table->string('name');
    $table->softDeletes();
    $table->timestamps();
});

Schema::create('search_firms_briefs', function(Blueprint $table)
{
    $table->increments('brief_id');
    $table->integer('client_id')->unsigned();
    $table->foreign('client_id')->references('client_id')->on('search_firms_clients')->onDelete('cascade');         
    $table->string('title');
    $table->softDeletes();
    $table->timestamps();
});

The model factory for each: 每个模型工厂:

$factory->define(App\SearchFirmClient::class, function ($faker) {
    return [
        'name'      => $faker->company,
        'email'     => $faker->companyEmail,
        'phone'     => $faker->phoneNumber,
        'address'   => $faker->address,
        'website'   => $faker->url,
    ];
});

$factory->define(App\SearchFirmBrief::class, function ($faker) {
    return [
        'user_id'       => 1,
        'title'         => $faker->sentence(3),
        'description'   => $faker->text(),
        'contact_id'    => 0,
    ];
});

The relationships: 关系:

class SearchFirm extends Model
{

    protected $table = 'search_firms';
    protected $primaryKey = 'id';

    public function clients() {
        return $this->hasMany('SearchFirmClient', 'search_firm_id');
    }
}

class SearchFirmClient extends Model
{

    use SoftDeletes;

    protected $table        = 'search_firms_clients';
    protected $primaryKey   = 'client_id';
    protected $dates        = [ 'deleted_at' ];


    public function briefs()
    {
        return $this->hasMany('SearchFirmBrief', 'client_id')->orderBy( 'updated_at', 'desc');
    }
}

class SearchFirmBrief extends Model
{

    use SoftDeletes;

    protected $table = 'search_firms_briefs';
    protected $primaryKey = 'brief_id';
    protected $touches = array('client');
    protected $dates = [ 'deleted_at'];

    public function client() {
        return $this->belongsTo('SearchFirmClient', 'client_id');
    }
}

Issue #1 第1期

There is no id column on the briefs table, but you are referencing it on the clients table. briefs表上没有id列,但是您在clients表上引用了它。

Change the foreign key to brief_id : 将外键更改为brief_id

Schema::create('search_firms_clients', function(Blueprint $table)
{
    $table->increments('client_id');
    $table->integer('search_firm_id')->unsigned();
    $table->foreign('search_firm_id')
          ->references('brief_id') // <-- Change this
          ->on('search_firms')
          ->onDelete('cascade');           
    $table->string('name');
    $table->softDeletes();
    $table->timestamps();
});

Schema::create('search_firms_briefs', function(Blueprint $table)
{
    $table->increments('brief_id');
    $table->integer('client_id')->unsigned();
    $table->foreign('client_id')->references('client_id')->on('search_firms_clients')->onDelete('cascade');         
    $table->string('title');
    $table->softDeletes();
    $table->timestamps();
});

Issue #2 第2期

You don't have a user_id member. 您没有user_id成员。

$factory->define(App\SearchFirmBrief::class, function ($faker) {
    return [
        'client_id'     => 1, // <-- change this
        'title'         => $faker->sentence(3),
        'description'   => $faker->text(),
        'contact_id'    => 0,
    ];
});

Conclusion 结论

It would be best if you follow Laravel's naming standards, it will save you a lot of headache in the future (ie use default table names, primary key names) 如果您遵循Laravel的命名标准,那将是最好的选择,它将在以后为您省去很多麻烦(例如,使用默认表名,主键名)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM