변경 사항이있는 경우에만 Laravel Eloquent 업데이트


87

해당 레코드가 변경된 경우 웅변 모델을 사용하여 Laravel에서 레코드를 업데이트하는 방법이 있습니까? 어떤 사용자도 정당한 이유없이 데이터베이스를 요청하는 것을 원하지 않습니다. 변경 사항을 저장하기 위해 버튼을 누르기 만하면됩니다. javascript페이지의 변경 여부에 따라 저장 버튼을 활성화 / 비활성화 하는 기능이 있지만 서버 측에서도 이러한 기능을 수행 할 수 있는지 알고 싶습니다. 레코드가 변경되었는지 확인하는 것만으로도 (프레임 워크의 내부 기능에 호소하지 않고) 혼자서 수행 할 수 있다는 것을 알고 있지만 그렇게하기 전에 Laravel eloquent 모델이 이미 처리하고 있는지 알고 싶습니다. 그래서 저는 바퀴를 다시 발명 할 필요가 없습니다.

이것이 내가 레코드를 업데이트하는 데 사용하는 방법입니다.

$product = Product::find($data["id"]);
$product->title = $data["title"];
$product->description = $data["description"];
$product->price = $data["price"];
//etc (string values were previously sanitized for xss attacks)
$product->save();

3
왜 쿼리 설득력이 실제로 당신이 할 때 실행을 확인하려면 데이터베이스 로깅을 활성화 한 다음 로그를 확인하지 않는 저장 : 당신이 놀랄 수도
마크 베이커

4
Laravel 모델 dirty에는 데이터베이스에 대한 업데이트가 실제로 필요한지 여부를 결정하는 데 사용되는 플래그 가 있으며이 플래그는 원래 find열 값을 저장을 실행 한 지점의 값과 비교하여 설정됩니다.
Mark Baker

@MarkBaker 훌륭한 팁입니다!
user2755140

답변:


180

당신은 이미하고 있습니다!

save()모델의 내용이 변경되었는지 확인합니다. 그렇지 않으면 db 쿼리를 실행하지 않습니다.

다음은 코드의 관련 부분입니다 Illuminate\Database\Eloquent\Model@performUpdate.

protected function performUpdate(Builder $query, array $options = [])
{
    $dirty = $this->getDirty();

    if (count($dirty) > 0)
    {
        // runs update query
    }

    return true;
}

getDirty()메서드는 현재 속성을 original모델이 생성 될 때 저장된 사본과 단순히 비교합니다 . 이것은 syncOriginal()방법 에서 수행됩니다 .

public function __construct(array $attributes = array())
{
    $this->bootIfNotBooted();

    $this->syncOriginal();

    $this->fill($attributes);
}

public function syncOriginal()
{
    $this->original = $this->attributes;

    return $this;
}

모델이 더러운 지 확인하려면 다음을 호출하십시오 isDirty().

if($product->isDirty()){
    // changes have been made
}

또는 특정 속성을 확인하려는 경우 :

if($product->isDirty('price')){
    // price has changed
}

훌륭합니다. 감사합니다. 변경하지 않고 업데이트를 시도했는지 알기 위해 더티 플래그에 액세스하려면 어떻게해야합니까? 내 말은 : 그 행동에 대한 반환?
user2755140

1
@DaseinA 당신은 그것을 사용할 수 있습니다 isDirty(). 업데이트 된 대답을 참조하십시오
lukasgeiter

2
이것을 읽는 사람들은 사용하기 전에이 답변 을 확인하십시오 isDirty().
Alex

1
getChanges()방법은. 내 대답을 확인하십시오. stackoverflow.com/a/54132163/1090395
Mladen Janjetovic

당신의 속성을 올바르게 캐스팅하지 않으면 FYI isDirty()가 될 것 true입니다. 데이터베이스에서와 똑같은 부동 소수점이 있었지만 문자열 (예 : 10.50 대신 "10.50")으로 부동 소수점을 설정했기 때문에 변경 사항을 감지하고 업데이트를 수행합니다.
Maarten de Graaf


11

이 메서드를 추가하고 싶습니다. 편집 양식을 사용하는 경우이 코드를 사용하여 update(Request $request, $id)함수 의 변경 사항을 저장할 수 있습니다.

$post = Post::find($id);    
$post->fill($request->input())->save();

동일한 열 이름으로 입력 이름을 지정해야합니다. 이 fill()기능은 모든 작업을 수행합니다. :)


3
이것은 실제로 내가 찾고 있던 대답이고, 이름을 잊어 버렸고 fill요청을 대량으로 전달하는 방법입니다. 감사! IM 업데이트 이후 ID를 전달할 필요가 없으므로 이미 있습니다 $request->id.
blamb
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.