2016-01-03 12 views
12

मैं एक खाद्य मेनू बना रहा हूं जिसे व्यवस्थापक ड्रैगिंग और ड्रॉप करके ऑर्डर/सॉर्ट कर सकता है। इस मेनू में कई श्रेणियां (उत्पाद श्रेणी) और उत्पाद (उत्पाद) शामिल हैं।लार्वेल बचत वाक्प्रचार मॉडल की क्रमबद्ध सूची

मैं नेस्टेड डी & डी की अनुमति देने के लिए क्लाइंट-साइड पर HTML5Sortable का उपयोग कर रहा हूं। मार्कअप बहुत सरल है:

<div class="categories"> 
    @foreach($categories as $category) 
    <div class="category"> 
     @foreach($category->products as $product) 
     <div class="products"> 
      <div class=""product" data=id="{{ $product->id }}"> 
       {{ $product->name }} 
      </div> 
     </div><!-- /products !--> 
     @endforeach 
    </div><!-- /category !--> 
    @endforeach 
</div> 

और इसी जावास्क्रिप्ट:

$('.categories').sortable({ 
    items: '.category' 
}); 
$('.products').sortable({ 
    items: '.product' 
}); 

// Will be called when the user is done repositioning the products and categories 
function getOrderedList() { 
    var data = {}; 

    $('.categories').find('.category').map(function(i) { 
     var category = $(this); 
     data[i] = {}; 
     data[i].id = category.data('id'); 
     data[i].products = category.find('.product').map(function() { 
      return $(this).data('id'); 
     }).get(); 
    }); 

    data = JSON.stringify(data); // Send data to server 
} 

समारोह getOrderedList JSON स्ट्रिंग वापस Laravel के लिए भेज देंगे, जो क्रमबद्ध श्रेणी आईडी की और उत्पाद आईडी के शामिल हैं:

{"0":{"id":1,"products":[2,3,1,4,5,6,7,8,9,10]},"1":{"id":2,"products":[11,12,13,14]},"2":{"id":3,"products":[15,16,17,18]}} 

मैं इस काम को बैक एंड पर कैसे बनाऊंगा? मुझे लगता है कि मुझे डेटाबेस में कहीं भी इस सरणी को स्टोर करना होगा और बाद में आईडी के मॉडल को ढूंढना और ऑर्डर करना होगा?

संक्षेप में: सॉर्टिंग (नेस्टेड) ​​मॉडल (लार्वेल के भीतर) के लिए एक साफ और लचीला समाधान क्या है?

उत्तर

5

एक आम सम्मेलन वजन है, उत्पाद तालिका पर (इंट) वजन नामक एक फ़ील्ड जोड़ें, जिसका उपयोग वस्तुओं के क्रम को परिभाषित करने के लिए किया जाता है।

एक बार आदेश में परिवर्तन होने पर आप केवल वज़न क्षेत्र को अपडेट करते हैं।

जब आप आइटम पुनर्प्राप्त करते हैं, तो आप उन्हें वजन से सॉर्ट करते हैं।

यह एक सरणी

Id  Name   Weight 
01  'product 1'  2 
02  'product 2'  0 
03  'product 3'  1 

के समान हो जाता है जब आप इसे वजन से आदेश मिल

product 2 
product 3 
product 1 

यह एक सरणी के समान है क्योंकि

$products[0] = 'product 2' 
$products[1] = 'product 3' 
$products[2] = 'product 1' 

नोट अगर आप चाहते हैं कि इसे और भी गतिशील बनाने के लिए, आप एक पोल बना सकते हैं यमोर्फिक मॉडल जो कई मॉडलों को संतुष्ट कर सकता है।

https://laravel.com/docs/5.1/eloquent-relationships#many-to-many-polymorphic-relations

बहुरूपी संबंध उदाहरण

बनाएं तालिका बाट (माइग्रेशन उदाहरण)

$table->increments('id'); 
$table->integer('value'); 
$table->integer('weightable_id')->unsigned(); 
$table->string('weightable_type'); 

बनाएं मॉडल भार को देखें

class Weight extends Eloquent 
{ 
    public function weightable() 
    { 
     return $this->morphTo(); 
    } 
} 

अब किसी भी अन्य मॉडल

class Products extends Eloquent 
{ 
    ... 
    public function weight() 
    { 
     return $this->morphOne(Weight::class); 
    } 
} 

इस तरह से साथ आप सिर्फ इतना है कि विधि आप तो आप इसके साथ अपने मॉडल सॉर्ट कर सकते हैं चाहते हैं किसी भी मॉडल के लिए जोड़ सकते हैं।

पीएससुनिश्चित करें कि किसी भी मॉडल यह का उपयोग करता है, बनाता है कि संबंध तुरंत मॉडल

मैं इस विधि की सलाह नहीं देते बनाने के बाद, यह बहुत बेहतर है अगर आप स्पष्ट रूप से उत्पाद तालिका में वजन फ़ील्ड निर्धारित, मैं समझता हूँ कि आप कितना चाहते हैं अपने कोड गतिशील होने के लिए है, लेकिन सब कुछ एक लागत

प्रदर्शन नीचे चला जाता है पर आता है, क्योंकि एक बार बहुरूपी संबंध स्थापित अपने कोड कल्पना करने के लिए आसान नहीं है, इसके अधिक उपयोग करने के लिए शुरू करने की तरह कार्य करने के बजाय कूद

+0

आपके उत्तर के लिए धन्यवाद, लेकिन मुझे पहले से ही यह पता था। मुझे लगता है कि मैं वास्तव में एक पॉलीमोर्फिक समाधान की तलाश में हूं जहां 'वज़न' कॉलम उत्पाद मॉडल में ही संग्रहीत नहीं किया जाएगा, इसलिए इसे इंगित करने के लिए धन्यवाद। – JasonK

+0

मैं –

2

सबसे पहले, जेएसओएन जो आप उत्पादन कर रहे हैं एक ऑब्जेक्ट नहीं होना चाहिए जहां कुंजी केवल सरणी सूचकांक हों।

[{"id":1,"products":[2,3,1,4,5,6,7,8,9,10]},{"id":2,"products":[11,12,13,14]},{"id":3,"products":[15,16,17,18]}] 

के बाद से products तालिका product_categories करने के लिए तालिका एक रिश्ते के लिए एक स्पष्ट कई है, तो आप सिर्फ products मेज पर product_categories_id विदेशी कुंजी का उपयोग करेंगे: इसके बजाय यह वस्तुओं की एक सरणी है कि इस तरह दिखता है होना चाहिए अपने JSON में रखे संबंधों का प्रतिनिधित्व करने के लिए।

आपके JSON के नेस्टेड वस्तुओं में, उत्पादों में हर मूल्य कुंजी सरणी है कि एक ही नेस्टेड वस्तु में आईडी कुंजी मान (इस पर स्तंभ product_category_id है से मेल खाती है एक विदेशी कुंजी होगा अपने products तालिका)।

आपका एपीआई endpoint समारोह तो कुछ इस तरह दिखेगा:

public function myApiEndpoint(){ 

    $input = Input::get('input'); 
    $input = json_decode($input, true); 
    foreach($input as $category){ 
     Product::whereIn('id', $category['products'])->update(array(
      'product_category_id' => $category['id'] 
     )); 
    } 

} 

मैं यहाँ एपीआई नियंत्रक में सीधे मॉडल को अद्यतन करने रहा हूँ, लेकिन क्या तुम सच में लगता है कि यह भी एक अंतरफलक को लागू है भंडार के माध्यम से किसी भी मॉडल परिवर्तन करना चाहिए ।

उपर्युक्त काम करेगा यदि आपके पास केवल एक मेनू (इसकी श्रेणियों और उत्पादों के साथ) है। यदि आप एकाधिक मेनू चाहते हैं, तो आपको एक तीन तरह की पिवट तालिका (कॉलम menu_id, product_id, और product_category_id के साथ) menus तालिका की आवश्यकता होगी।

+0

में पॉलीमोर्फिक समाधान को शामिल करने के उत्तर को संपादित कर दूंगा, आप उत्पाद मॉडल के भीतर 'category_id' को अपडेट कर रहे हैं, मुझे नहीं लगता कि यह मेरे' sortable 'प्रश्न से कैसे संबंधित है। – JasonK

+0

@ जेसनके आप पूछ रहे हैं कि उपयोगकर्ता द्वारा चुने गए उत्पादों और श्रेणियों के संयोजन को कैसे सहेजना है। यदि आप एक अलग सवाल पूछ रहे हैं, तो आपको वास्तव में जाना चाहिए और संशोधित करना चाहिए कि आपने अपना प्रश्न कैसे phrased किया –

संबंधित मुद्दे