[php] Laravel Check 관련 모델이 존재하는 경우

관련 모델이있는 Eloquent 모델이 있습니다.

public function option() {
    return $this->hasOne('RepairOption', 'repair_item_id');
}

public function setOptionArrayAttribute($values)
{
    $this->option->update($values);
}

모델을 만들 때 반드시 관련 모델이있는 것은 아닙니다. 업데이트 할 때 옵션을 추가하거나 추가하지 않을 수 있습니다.

따라서 관련 모델이 있는지 확인하고 업데이트하거나 생성하려면 각각 다음을 수행해야합니다.

$model = RepairItem::find($id);
if (Input::has('option')) {
    if (<related_model_exists>) {
        $option = new RepairOption(Input::get('option'));
        $option->repairItem()->associate($model);
        $option->save();
        $model->fill(Input::except('option');
    } else {
       $model->update(Input::all());
    }
};

<related_model_exists>내가 찾고있는 코드는 어디에 있습니까 ?



답변

PHP 7.2 이상 에서는 count관계 객체를 사용할 수 없으므로 모든 관계에 대해 하나의 모든 방법이 없습니다. 아래 제공된 @tremby와 같이 대신 쿼리 방법을 사용하십시오.

$model->relation()->exists()

모든 관계 유형에서 작동하는 일반 솔루션 ( php 7.2 이전 ) :

if (count($model->relation))
{
  // exists
}

동적 속성을 반환하기 때문에이 모든 관계에 대해 작동합니다 ModelCollection. 둘 다 구현 ArrayAccess합니다.

따라서 다음과 같이 진행됩니다.

단일 관계 : hasOne / belongsTo/ morphTo/morphOne

// no related model
$model->relation; // null
count($model->relation); // 0 evaluates to false

// there is one
$model->relation; // Eloquent Model
count($model->relation); // 1 evaluates to true

다 대다 관계 : hasMany / belongsToMany/ morphMany/ morphToMany/morphedByMany

// no related collection
$model->relation; // Collection with 0 items evaluates to true
count($model->relation); // 0 evaluates to false

// there are related models
$model->relation; // Collection with 1 or more items, evaluates to true as well
count($model->relation); // int > 0 that evaluates to true


답변

관계 객체는 을 통해 알 수없는 메소드 호출에 전달 웅변 쿼리 빌더 에만 관련 개체를 선택하도록 설정되어 있습니다. 빌더 턴에 이르기까지 알 수없는 메소드 호출 전달 기본 쿼리 빌더 .

이는 관계 객체에서 직접 exists()또는 count()메소드를 사용할 수 있음을 의미 합니다.

$model->relation()->exists(); // bool: true if there is at least one row
$model->relation()->count(); // int: number of related rows

후 괄호 참고 relation: ->relation()함수 호출 (관계 개체를 받고)에 반대한다 ->relation하는 Laravel에 의해 당신을 위해 설정 마법 속성 게터는 (관련 객체 / 객체를 받고).

은 Using count(괄호를 사용)의 관계 개체의 방법은 훨씬 더 빨리하는 것보다 것 $model->relation->count()또는 count($model->relation)그것을 실행하기 때문에 (의 관계는 이미 열망로드되지 않는 한) 카운트 쿼리가 아니라 관련된 모든 개체에 대한 모든 데이터를 당기는 것보다 데이터베이스에서 계산하기 만하면됩니다. 마찬가지로를 사용 exists하면 모델 데이터를 가져올 필요가 없습니다.

모두 exists()count()내가 해봤 모든 관계 유형에 대한 작업, 너무 적어도 belongsTo, hasOne, hasMany,와 belongsToMany.


답변

exists방법 을 사용하는 것을 선호합니다 .

RepairItem::find($id)->option()->exists()

관련 모델이 존재하는지 확인합니다. Laravel 5.2에서 잘 작동합니다.


답변

Php 7.1 이후 에는 허용 된 답변이 모든 유형의 관계에 적용되지 않습니다.

관계 유형에 따라 Eloquent는 a Collection, a Model또는을 반환합니다 Null. 그리고 Php 7.1 count(null) 에서는 error.

따라서 관계가 존재하는지 확인하려면 다음을 사용할 수 있습니다.

관계를위한 단일 예를 들어 hasOnebelongsTo

if(!is_null($model->relation)) {
   ....
}

관계가 여러 개인 경우 : 예 : hasManybelongsToMany

if ($model->relation->isNotEmpty()) {
   ....
}


답변

이것이 Laravel 5에서 변경되었는지 확실 count($data->$relation)하지 않지만 관계 속성에 액세스하는 행위로 인해로드가 발생했기 때문에 허용 된 답변이 효과 가 없었습니다.

결국, 솔직히 isset($data->$relation)나를 위해 속임수를 썼습니다.


답변

모델 객체 에서 relationLoaded 메서드를 사용할 수 있습니다 . 이것은 내 베이컨을 구해 주었기 때문에 다른 누군가에게 도움이되기를 바랍니다. 나는 한 이 제안을 주어 내가 Laracasts에 같은 질문을 할 때.


답변

로 Hemerson 바렐라는 이미 PHP는 7.1에서 말했다 count(null)발생합니다 errorhasOne수익을 null더 행이 존재하지 않는 경우. hasOne관계 가 있기 때문에이 empty방법을 사용하여 확인합니다.

$model = RepairItem::find($id);
if (!empty($temp = $request->input('option'))) {
   $option = $model->option;

   if(empty($option)){
      $option = $model->option()->create();
   }

   $option->someAttribute = temp;
   $option->save();
};

그러나 이것은 불필요한 것입니다. 관계가 존재하는지 확인 update하거나 create전화를 걸지 여부를 결정할 필요가 없습니다 . updateOrCreate 메소드를 사용하십시오 . 이것은 위와 같습니다.

$model = RepairItem::find($id);
if (!empty($temp = $request->input('option'))) {
   $model->option()
         ->updateOrCreate(['repair_item_id' => $model->id],
                          ['option' => $temp]);
}