পিভট টেবিলটিতে একাধিক রেকর্ড যুক্ত করে লারাভেলকে আটকাচ্ছে


100

আমার ব্যবহৃত কার্টটিতে একটি আইটেম যুক্ত করতে আমার অনেকের সাথে অনেকগুলি সম্পর্ক স্থাপন এবং কাজ করছে:

$cart->items()->attach($item);

যা পাইভট টেবিলটিতে একটি আইটেম যুক্ত করে (যেমনটি হওয়া উচিত) তবে ব্যবহারকারীরা ইতিমধ্যে যুক্ত করা আইটেম যুক্ত করতে যদি আবার লিঙ্কটিতে ক্লিক করেন তবে এটি পিভট টেবিলটিতে একটি সদৃশ এন্ট্রি তৈরি করে।

একটি ইতিমধ্যে বিদ্যমান না থাকলে কেবল একটি পিভট টেবিলের সাথে একটি রেকর্ড যুক্ত করার উপায় রয়েছে কি?

যদি তা না হয় তবে কোনও মিলের রেকর্ড ইতিমধ্যে উপস্থিত রয়েছে কিনা তা জানতে আমি কীভাবে পাইভট টেবিলটি পরীক্ষা করতে পারি?

উত্তর:


78

আপনি এটির মতো খুব সাধারণ শর্তটি লিখে কোনও বিদ্যমান রেকর্ডের উপস্থিতি যাচাই করতে পারেন:

if (! $cart->items->contains($newItem->id)) {
    $cart->items()->save($newItem);
}

অথবা / এবং আপনি আপনার ডাটাবেসে ইউনিটিসিটি শর্ত যুক্ত করতে পারেন, এটি একটি ডাবলট সংরক্ষণের প্রয়াসের সময় একটি ব্যতিক্রম ছুঁড়ে ফেলবে।

আপনার ঠিক নীচে ব্যারিভধের আরও সোজা উত্তরটি দেখুন।


4
পদ্ধতির জন্য আইডি প্যারামিটারটি attach()মিশ্রিত করা হয়েছে, এটি কোনও মডেলের উদাহরণ বা উদাহরণ হতে পারে;) - github.com/laravel/framework/blob/master/src/Illuminate/… দেখুন
রব

ধন্যবাদ @ রবগোর্দিজন আমি আজ কিছু শিখেছি! উত্তর সম্পাদিত।
আলেকজান্দ্রে বুটিনস্কি

4
@ ব্যাগসফ্লাইয়ার containsস্টেটমেন্টটি দেখুন কীটিতে সংগ্রহে একটি বস্তুর উপস্থিত রয়েছে কিনা check আপনার কোডে ভুল হওয়া উচিত।
আলেকজান্দ্রে বুটিনস্কি

4
আমি এই সমাধানটি পছন্দ করি না কারণ এটি একটি অতিরিক্ত ক্যোয়ারিকে জোর করে ($ কার্ট-> আইটেমগুলি) আমি এমন কিছু করছি: $cart->items()->where('foreign_key', $foreignKey)->count() যা ভাল, আসলে একটি অতিরিক্ত ক্যোরিও সম্পাদন করে '^^ তবে আমার আনার দরকার নেই এবং আমার যদি সত্যিই এটির প্রয়োজন না হয় তবে পুরো সংগ্রহটি হাইড্রেট করুন।
নীরবতা

4
এটা ঠিক, আপনার সমাধানটি আরও কিছুটা অনুকূলিত হয়েছে। এমনকি সর্বোত্তম অনুকূলকরণের exists()পরিবর্তে আপনি ফাংশনটি ব্যবহার করতে পারেন count()
আলেকজান্দ্রে বুটিনস্কি

267

এছাড়াও আপনি এই $model->sync(array $ids, $detaching = true)পদ্ধতিটি ব্যবহার করতে পারেন এবং বিচ্ছিন্নকরণ (দ্বিতীয় প্যারাম) অক্ষম করতে পারেন ।

$cart->items()->sync([$item->id], false);

আপডেট: লারাভেল 5.3 বা 5.2.44 সাল থেকে আপনি সিঙ্ক উইথআউটডেটিচিংয়েও কল করতে পারেন:

$cart->items()->syncWithoutDetaching([$item->id]);

যা ঠিক একই কাজ করে তবে আরও পাঠযোগ্য :)


4
তালিকাভুক্ত আইডি বিচ্ছিন্নকরণ প্রতিরোধের দ্বিতীয় বুলিয়ান প্যারামিটারটি মূল এল 5 ডকুমেন্টেশনে নেই। এটি জেনে রাখা খুব ভাল - একক বিবৃতিতে "ইতিমধ্যে সংযুক্ত না থাকলে সংযুক্তি" করার একমাত্র উপায় বলে মনে হয়।
জেসন

11
এটি উত্তর হিসাবে গ্রহণ করা উচিত, গৃহীত উত্তরের চেয়ে এটি করা আরও ভাল উপায়
ড্যানিয়েল

4
আমার মত নতুনদের জন্য: $cart->items()->sync([1, 2, 3])প্রদত্ত অ্যারের মধ্যে আইডি এর অনেক সাথে অধিকের সম্পর্ক গঠন করা হবে, 1, 2, এবং 3এবং মুছুন (বা "আলাদা") সব অন্যান্য ID নয় অ্যারের মধ্যে আছে। এইভাবে, কেবল অ্যারেতে দেওয়া আইডি টেবিলটিতে উপস্থিত থাকবে। উজ্জ্বল @ বার্যিভিধ্ সেই ডিটাচিংটি অক্ষম করতে একটি অনিবন্ধিত দ্বিতীয় প্যারামিটার ব্যবহার করে, সুতরাং প্রদত্ত অ্যারেতে কোনও সম্পর্ক মুছে ফেলা হয় না তবে কেবল অনন্য আইডি সংযুক্ত করা হবে। "কনভেনিয়েন্সের জন্য সিঙ্কিং" ডকটি দেখুন। (
লারাভেল

4
এফওয়াইআই, আমি ডকগুলি আপডেট করেছি, সুতরাং 5.2 এবং তার বেশি: লারাভেল ডকস / ডকস / ৫.২/ এবং টেলর তত্ক্ষণাত যুক্ত যুক্ত করেছেন syncWithoutDetaching(), যা সিঙ্ককে () সিঙ্ক হিসাবে দ্বিতীয় প্যারাম বলে calls
ব্যারিভধ

লারাভেল 5.5 লারাভেল ডটকম / ডকস / 5.5 /…syncWithoutDetaching() কাজ করেছেন!
জোশ লামার

2

@ আলেক্সান্দ্রে বাটিনস্কি পদ্ধতিটি খুব ভালভাবে কাজ করে তবে দুটি স্কয়ার কোয়েরি ব্যবহার করে।

কার্টে আইটেম রয়েছে কিনা তা যাচাই করতে হবে এবং একটিতে সংরক্ষণ করতে হবে।

শুধুমাত্র একটি ক্যোয়ারী ব্যবহার করতে এটি ব্যবহার করুন:

try {
    $cart->items()->save($newItem);
}
catch(\Exception $e) {}

আমার প্রকল্পে এটিই আমি করেছি। তবে সমস্যাটি আপনি জানেন না যে এই ব্যতিক্রমটি সদৃশ এন্ট্রি বা অন্য কোনও কারণে হয়েছে।
বাগসফ্লায়ার

4
কেন এটি কোনও ব্যতিক্রম ছুঁড়ে ফেলবে? এটি যদি কোনও অনন্য কী থাকে তবে
সেজি মনোয়ন

1

এই সমস্ত উত্তরগুলির মতোই দুর্দান্ত কারণ আমি সেগুলি সব চেষ্টা করে দেখেছি, একটি জিনিস এখনও অব্যাহত রেখে গেছে বা যত্ন নেওয়া হয়নি: পূর্ববর্তী চেক করা মানটি আপডেট করার বিষয়টি (চেক করা বাক্সটি চেক করা হয়নি [এস])। আমার উপরোক্ত প্রশ্নের অনুরূপ কিছু রয়েছে বলে আমি আশা করি যে আমি আমার পণ্য-বৈশিষ্ট্য সারণীতে (পিভট টেবিল) পণ্যগুলির বৈশিষ্ট্যগুলি পরীক্ষা করতে এবং চেক করতে চাই। আমি একজন নবাগত এবং আমি বুঝতে পেরেছি যে উপরের কেউই এটি করেনি। নতুন বৈশিষ্ট্য যুক্ত করার সময় উভয়ই ভাল তবে যখন আমি বিদ্যমান বৈশিষ্ট্যগুলি মুছে ফেলতে চাই না (অর্থাত এটি চেক করুন)

আমি এ সম্পর্কে যে কোনও জ্ঞানার্জনের প্রশংসা করব।

$features = $request->get('features');

if (isset($features) && Count($features)>0){
    foreach ($features as $feature_id){
        $feature = Feature::whereId($feature_id)->first();
        $product->updateFeatures($feature);
    }
}

//product.php (extract)
public function updateFeatures($feature) {
        return $this->features()->sync($feature, false);
}

বা

public function updateFeatures($feature) {
   if (! $this->features->contains($features))
        return $this->features()->attach($feature);
}
//where my attach() is:
public function addFeatures($feature) {
        return $this->features()->attach($feature);
}

দুঃখিত বন্ধুরা, নিশ্চিত না যে আমার নিজের প্রশ্নটি মুছে ফেলা উচিত কারণ উত্তরটি নিজেই খুঁজে বের করা, এটি কিছুটা বোকা মনে হচ্ছে, ঠিক উপরের উত্তরটি @ বার্যিভিএইচডি সিঙ্ক () হিসাবে কাজ করার মতোই নীচের মত সহজ; সম্পর্কে আরও এবং আরও পড়ার:

$features = $request->get('features');
if (isset($features) && Count($features)>0){
    $product->features()->sync($features);
}

0

ইতিমধ্যে কিছু দুর্দান্ত উত্তর পোস্ট করা হয়েছে। যদিও আমি এটিকে এখানে ফেলে দিতে চাইছিলাম।

@ অ্যালেক্সান্দ্রেবুটেনস্কি এবং @ ব্যারিভধের উত্তরগুলি আমার পরামর্শের চেয়ে বেশি পঠনযোগ্য, এই উত্তরটি যা যুক্ত করে তা হ'ল কিছু দক্ষতা।

এটি কেবলমাত্র বর্তমান সংমিশ্রনের (কেবলমাত্র আইডি) কেবলমাত্র এন্ট্রি পুনরুদ্ধার করে এবং এটি উপস্থিত না থাকলে এটি সংযুক্তি করে। সিঙ্ক পদ্ধতি (এমনকি কোনও বিচ্ছিন্নতা ছাড়াই) বর্তমানে সংযুক্ত সমস্ত আইডি পুনরুদ্ধার করে। অল্প পুনরাবৃত্তির সাথে ছোট সেটগুলির জন্য এটি খুব কমই একটি পার্থক্য হতে পারে, ... আপনি আমার বিষয়টি পেয়ে যান।

যাইহোক, এটি অবশ্যই পঠনযোগ্য নয়, তবে এটি কৌশলটি করে।

if (is_null($book->authors()->find($author->getKey(), [$author->getQualifiedKeyName()])))
    $book->authors()->attach($author);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.