2016-09-05 1 views
1

사용자가 이미지를 표시하도록 설정하려면 다른 모든 이미지를 featured이 아닌 것으로 재설정해야합니다. 나는 다음과 같은 raw SQL 쿼리를 사용하여이 작업을 수행했습니다.원시 SQL 쿼리 대신 ORM을 사용하여 값을 업데이트하는 방법은 무엇입니까?

ORM을 사용하여이 작업을 수행하는 더 깨끗한 방법이 있습니까? 아니면이 유형의 경우에는 그대로 유지하는 것이 더 깔끔합니까? 이 같은

<?php 

class Banner extends DataObject { 
    private static $db = array(
     'FeaturedImage' => 'Boolean' 
    ); 

    private static $has_one = array(
     'Image' => 'Image' 
    ); 

    private static $summary_fields = array(
     'Image.CMSThumbnail' => 'Image', 
     'FeaturedImage.Nice' => 'Featured?' 
    ); 

    public function onBeforeWrite() 
    { 
     parent::onBeforeWrite(); 

     // When user sets an image to be featured, reset all other images not to be featured 
     if ($this->FeaturedImage) { 
      $query = 'UPDATE Banner SET FeaturedImage = 0 WHERE Banner.ID !=' . $this->ID; 
      DB::query($query); 
     } 
    } 
} 
+0

greg이 onAfterWrite에서 최고라고 말하지만, 다시 한번 CMSAction의 일종을 만들고 이것을 "해킹"하지 말아야합니다. – Barry

+1

@ifusion cleaner, well ... 그러나 하나의 옵션은 배너 객체를 드롭 다운 또는 listboxfiled 당 하나의 bannerobjects에 보유하는 동일한 객체의 has_one 옵션입니다. – munomono

답변

2

이미이 (죄송합니다, 주석으로이를 추가 할 수 없습니다) 시도 했습니까?

public function onAfterWrite() 
{ 
    parent::onAfterWrite(); 

    if ($this->FeaturedImage) { 
     $banners = Banner::get()->exclude('ID', $this->ID); 
     foreach($banners as $banner) { 
      $banner->FeaturedImage = false; 
      $banner->write(); 
     } 
    } 
} 

조건은 쓰기의 재귀 호출을 방지해야합니다.

+0

완벽하게, 이제 제대로 작동합니다. – ifusion

1

뭔가 :

$banners = Banner::get()->exclude('ID', $this->ID); 
foreach($banners as $banner) { 
    $banner->FeaturedImage = 0; 
    $banner->write(); 
} 
+0

아니요, 오류가 발생합니다. '치명적인 오류 :'256 '의 최대 기능 중첩 수준에 도달했습니다. in Unknown in line 0' – ifusion

+1

당신은 onAfterWrite() 안에 시도 했습니까? –

+1

onBeforeWrite 및 onAfterWrite는 Image 객체가 처리 될 때마다 실행되므로 여기서는 작동하지 않습니다. 그래서 당신은'$ banner-> FeaturedImage = 0; $ banner-> write()'그러면 $ Banner에 onBeforeWrite와 onAfterWrite가 다시 실행됩니다. 그것은 무한 루프에 빠지게됩니다. AFAIK, 유일한 방법은 현재 수행중인 원시 쿼리입니다. –