Laravel firstOrCreate搜索关系

时间:2018-05-30 09:18:18

标签: php laravel eloquent

我想使用Eloquent的firstOrCreate函数。我的数据的相关部分是属于国家和国家的运动员,他们拥有许多运动员。 (一对多关系)

class Athlete extends Model
{
  public $timestamps = false;
  protected $fillable = ['firstname', 'lastname', 'nation'];
.....
  public function nation()
  {
      return $this->belongsTo('App\Nation');
  }
}

class Nation extends Model
{
  public $timestamps = false;
...
  public function athletes()
  {
      return $this->hasMany('App\Athlete');
  }
}

如果我还需要检查国家,我如何使用firstOrCreate?

都不是

$ath = Athlete::firstOrCreate(['nation_id'=>$nation->id, 'lastname'=>$nn, 'sex'=>$sex, 'firstname'=>$vn] );

,也不

$ath = Athlete::firstOrCreate(['nation'=>$nation, 'lastname'=>$nn, 'sex'=>$sex, 'firstname'=>$vn] );

的工作。

第一种情况:

  

“Nation_id没有默认值”

第二种情况:

  

Laravel尝试使用传递的对象构建WHERE语句   显然不起作用。

我可以在这里使用firstOrCreate吗?

谢谢。

2 个答案:

答案 0 :(得分:1)

首先在 $ fillable 受保护字段中,您已为与DB相关的 country 字段加下划线。 根据这一点,我在第二次尝试查询中不了解 nation_id 字段。

在关系声明中,请为外键加下划线,以便两个字段(nation和nation_id)之间的差异变得清晰。

假设 country 字段包含与Nations'的关系。记录(主要唯一ID上的匹配关系),您可以比较此ID上的提供数据(用于国家比较),而不是所有国家/地区字段。

然后你报告的第一个案例我错了

  

第一种情况:" Nation_id没有默认值"

因为这意味着您在没有提供国家ID的情况下插入运动员,并且结果是在查询构建器中未检查此ID(可能因为为null)。 通过这种方式,如果国家为空,你就不会与当前的运动员和现有的运动员进行比较。

一般情况下,我建议您按照以下步骤完成任务:

  1. 检查传递给查询构建器的所有数据是否正确
  2. 以这种方式编写查询

    $ath = Athlete::firstOrCreate(['field_that_contains_nation_id'=>$nation->id, 'other_athlete_fields' => $value, ...] );
    

    然后运行此模型的操作

    $ath->save();
    

    如果您想知道是否创建了记录:

    if($ath->wasRecentlyCreated){
        echo 'Created successfully';
    } else {
        echo 'Already exist';
    }
    
  3. 如果已经不起作用,请检查关系是否在表格中正确设置。

答案 1 :(得分:0)

$fillable必须包含列名,而不是关系名。此外,sex缺失:

protected $fillable = ['firstname', 'lastname', 'sex', 'nation_id'];