2015-07-08 23 views
14

Bileşik bir anahtarı olan bir ilişki tarafından birleştirilen 2 modelim var - bunlar Ürün ve Kategori. Tüm tablolarda yumuşak silmeler kullanmam gerekiyor, bu nedenle modeller ve ilişkiler gerektiğinde geri yüklenebilir. Benim Ürün modelindeBileşik anahtarlarla ilişkiyi silme/ayırma ve geri yükleme/geri yükleme

Ben: Benim Kategori modelinde

function categories() 
{ 
    return $this->belongsToMany('App\Category', 'product_categories')->whereNull('product_categories.deleted_at')->withTimestamps(); 
} 

Ben: $category->products->contains($product->id) gibi sorgular aksi yumuşak dönen gibi

function products() 
{ 
    return $this->belongsToMany('App\Product', 'product_categories')->whereNull('product_categories.deleted_at')->withTimestamps(); 
} 

ben başka bir yerde whereNull yöntemi zincirleme hakkında okumak ilişki silindi.

Sorgu, bu silinen ilişkiyi silme ve geri yükleme işlemlerini gerçekleştirmenin en iyi yolu nedir? örneğin, geri, ben denedim: (Bu product_categories için kategoriler tablosunu katıldığı için)

$product->categories()->restore($category_id); 

yukarıda deleted_at alan belirsiz olduğunu söyleyerek bir SQL hatası üretti.

Güncelleştirmesi - Kök sorun, sahip olduğu boşluğun görünürTMany sınıfının yumuşak silme işlemlerini desteklememesidir. Bu nedenle, ekleme, çıkarma ve eşitleme işlemlerinin tümünü silmeleri gerçekleştirir. Bu dersi geçersiz kılacak en iyi yaklaşım hangisi olurdu?

// SoftDeletePC.php 
trait SoftDeletePC { 
    // SoftDelete 
    public function softDeleteProductCategory($productId, $categoryId) 
    { 
     \DB::table('product_categories') 
     ->where('product_id', $productId) 
     ->where('category_id', $categoryId) 
     ->update(['deleted_at' => \DB::raw('NOW()')]); 
    } 

    // Restore 
    public function restoreProductCategory($productId, $categoryId) 
    { 
     \DB::table('product_categories') 
     ->where('product_id', $productId) 
     ->where('category_id', $categoryId) 
     ->update(['deleted_at' => null]); 
    } 
} 
: Temelde

cevap

5

, orada sadece bir deleted_at alan olabilir ve bunun yerine $product->categories() kullanımı iki özel (yaygın) hem de yöntemleri ( Product ve Category) örneğin modelleri kullanmanın olacak, böyle bir özelliği yaratabilir

Sonra use TraitProductCategory kullanarak iki modelde de bu özellik kullanabilir ve örneğin hem modellerden yöntemini çağırın: yerine bu kullanmak yerine, Yani

// App/Product.php 
class product extends Model { 
    use SoftDeletePC; 
} 

// App/Category.php 
class Category extends Model { 
    use SoftDeletePC; 
} 

:

Product->find(1)->categories()->restore(2); 

Böyle bir şey kullanabilir:

$product = Product->find(1); 

$product->softDeleteProductCategory(1, 2); // Set timestamp to deleted_at 

$product->restoreProductCategory(1, 2); // Set null to deleted_at 

Umut bu sizin için çalışabilir.

+0

teşekkürler. Sadece Laravel ile çalışmaya başladım ve daha önce hiç bir şeyle karşılaşmadım. Yaklaşımınız aslında ortaya çıkmış olana benziyor - yani bunun üstesinden gelmek için özel yöntemler. İdeal olarak, basit yöntemlerin yumuşak silme işlemlerini desteklemesini istiyorum - dürüst olmak gerekirse, bunun ne kadar mümkün olduğundan emin değilim. Bir yanıt olarak kendi oluşturduğum senkronizasyon sürümümü göndereceğim. – BrynJ

1

Ürün modelimde gereksinim duyduğum şeyi gerçekleştirmek için bazı özel yöntemler oluşturmayı bitirdim - ideal çözümüm değil, ancak yine de çalışıyor. Benim özel bir senkronizasyon şöyle görünür: Yukarıdaki

class Product extends Model 
{ 
    // update relationship to categories 
    function categories_sync($category_ids) 
    { 
     // categories 
     $existing_category_ids = $this->categories()->lists('category_id')->all(); 
     $trashed_category_ids = $this->categories('onlyTrashed')->lists('category_id')->all(); 

     if(is_array($category_ids)) { 

      foreach($category_ids as $category_id) { 
       if(in_array($category_id, $trashed_category_ids)) { 
        $this->categories()->updateExistingPivot($category_id, ['deleted_at' => null]); 
       } 
       elseif(!in_array($category_id, $existing_category_ids)) { 
        $this->categories()->attach($category_id); 
       } 
      } 

      foreach($existing_category_ids as $category_id) { 
       if(!in_array($category_id, $category_ids)) { 
        $this->categories()->updateExistingPivot($category_id, ['deleted_at' => date('YmdHis')]); 
       } 
      } 
     } 
     else { 
      foreach($existing_category_ids as $category_id) { 
       $this->categories()->updateExistingPivot($category_id, ['deleted_at' => date('YmdHis')]); 
      } 
     } 
    } 
} 

uzatılmış kategorilerde dayanır() yöntemi: öneri için

// relationship to categories 
function categories($trashed=false) 
{ 
    if($trashed=='withTrashed') { 
     return $this->belongsToMany('App\Category', 'product_categories')->withTimestamps(); 
    } 
    elseif($trashed=='onlyTrashed') { 
     return $this->belongsToMany('App\Category', 'product_categories')->whereNotNull('product_categories.deleted_at')->withTimestamps(); 
    } 
    else { 
     return $this->belongsToMany('App\Category', 'product_categories')->whereNull('product_categories.deleted_at')->withTimestamps(); 
    } 
} 
İlgili konular