লারাভেল - স্বতঃস্ফূর্ত "has", "সহ", "কোথায়" - এর অর্থ কী?


210

আমি ধারণা পাওয়া যায় এবং এই পদ্ধতি পিছনে অর্থ একটু বিভ্রান্তিকর হতে করেছেন, এটা কেউ আমাকে বুঝিয়ে বলতে পারেন সম্ভব কি মধ্যে পার্থক্য hasএবং withএকটি উদাহরণ প্রেক্ষাপটে (সম্ভব হলে) এ, কে?

উত্তর:


553

সঙ্গে

with()জন্য উৎসুক লোড । মূলত এর অর্থ হ'ল মূল মডেলটি বরাবর, লারাভেল আপনার নির্দিষ্ট করা সম্পর্কের (গুলি) প্রিলোড করবে। এটি বিশেষত সহায়ক যদি আপনার কাছে মডেলগুলির একটি সংগ্রহ থাকে এবং আপনি তাদের সকলের জন্য একটি সম্পর্ক লোড করতে চান। কারণ আগ্রহী লোডিংয়ের সাথে আপনি সংগ্রহে প্রতিটি মডেলের পরিবর্তে কেবলমাত্র একটি অতিরিক্ত ডিবি ক্যোয়ারী চালান।

উদাহরণ:

User > hasMany > Post

$users = User::with('posts')->get();
foreach($users as $user){
    $users->posts; // posts is already loaded and no additional DB query is run
}

আছে

has()সম্পর্কের ভিত্তিতে বাছাই করা মডেলটি ফিল্টার করা। সুতরাং এটি একটি সাধারণ WHOE অবস্থার সাথে খুব একইভাবে কাজ করে। যদি আপনি কেবল তার ব্যবহার করেন তবে আপনি কেবলমাত্র has('relation')এই সম্পর্কের সাথে সম্পর্কিত মডেলগুলি পেতে চান।

উদাহরণ:

User > hasMany > Post

$users = User::has('posts')->get();
// only users that have at least one post are contained in the collection

WhereHas

whereHas()মূলত একইরূপে কাজ করে has()তবে আপনাকে পরীক্ষা করতে সংশ্লিষ্ট মডেলটির জন্য অতিরিক্ত ফিল্টার নির্দিষ্ট করার অনুমতি দেয়।

উদাহরণ:

User > hasMany > Post

$users = User::whereHas('posts', function($q){
    $q->where('created_at', '>=', '2015-01-01 00:00:00');
})->get();
// only users that have posts from 2015 on forward are returned

101
+1, খুব সহায়ক উত্তর! উল্লেখ্য যে যখন with('relation')ফিরে সংগ্রহে সংশ্লিষ্ট টেবিল ডেটা অন্তর্ভুক্ত করা হবে, has('relation')এবং whereHas('relation')হবে না সংশ্লিষ্ট টেবিল ডেটা অন্তর্ভুক্ত। সুতরাং আপনার with('relation')পাশাপাশি পাশাপাশি has()বা উভয়কে কল করার প্রয়োজন হতে পারে whereHas()
সোলারিসার

1
গ্রেট উত্তর, কীভাবে সম্পর্কের মডেল থেকে পিতামাতার মডেলটি অ্যাক্সেস করবেন তা এখানে উদাহরণস্বরূপ কীভাবে ব্যবহারকারীর মডেলের বৈশিষ্ট্যের উপর ভিত্তি করে পোস্ট মডেলটি অনুসন্ধান করবেন
hussainfrotan

@ ভোজেন্দ্রনেপল দুর্ভাগ্যক্রমে ডক্সে এটি সম্পর্কে খুব বেশি কিছু নেই বলে মনে হচ্ছে ... এটাই আমি খুঁজে পেয়েছি (এটি কয়েকটি অনুচ্ছেদ নীচে রয়েছে)
লুকাসেজিটার

@ হুসাইনফ্রোটান একইভাবে, whereHasপোস্ট জিজ্ঞাসা করার সময় ব্যবহারকারীর সম্পর্কের উপর ব্যবহার করুন।
মাইকেল স্যাং

অদ্ভুত, Laravel ডকুমেন্টেশনে: laravel.com/docs/5.8/eloquent-relationships যখন ব্যবহার whereHasএটি ব্যবহার করে use Illuminate\Database\Eloquent\Builder;যা পরে সাথে আছেন function(Builder $query)। বেশিরভাগ উদাহরণ যা আমি দেখেছি, বিন্দুটি ব্যবহার করে Builder, $ কোয়েরিটি পাস করুন, কোনটি সঠিক?
গুন্টার

8

দস্তাবেজ ইতিমধ্যে ব্যবহারের ব্যাখ্যা দিয়েছে। সুতরাং আমি এই পদ্ধতিগুলি ব্যাখ্যা করতে এসকিউএল ব্যবহার করছি

উদাহরণ:


ধরে নিচ্ছি সেখানে Order (orders)অনেক রয়েছে OrderItem (order_items)

এবং আপনি ইতিমধ্যে তাদের মধ্যে সম্পর্ক তৈরি করেছেন।

// App\Models\Order:
public function orderItems() {
    return $this->hasMany('App\Models\OrderItem', 'order_id', 'id');
}

এই তিনটি পদ্ধতি সবই একটি সম্পর্কের উপর ভিত্তি করে

সঙ্গে


ফলাফল: with() মডেল অবজেক্ট এবং এর সম্পর্কিত ফলাফলগুলি ফিরিয়ে দিন।

সুবিধা: এটি আগ্রহী-লোডিং যা এন + 1 সমস্যা রোধ করতে পারে

আপনি যখন নিম্নলিখিত বর্ণনাকারী নির্মাতা ব্যবহার করছেন:

Order::with('orderItems')->get();

লারাভেল এই কোডটি কেবল দুটি এসকিউএল- তে পরিবর্তন করুন :

// get all orders:
SELECT * FROM orders; 

// get the order_items based on the orders' id above
SELECT * FROM order_items WHERE order_items.order_id IN (1,2,3,4...);

এবং তারপরে লারাভেল দ্বিতীয় এসকিউএলের ফলাফলগুলি বিদেশী কী দ্বারা প্রথম এসকিউএল এর ফলাফল থেকে আলাদা হিসাবে মার্জ করে । শেষ অবধি সংগ্রহের ফলাফল।

সুতরাং যদি আপনি বন্ধ হয়ে বিদেশী_কি ছাড়া কলামগুলি নির্বাচন করেন তবে সম্পর্কের ফলাফলটি খালি হবে:

Order::with(['orderItems' => function($query) { 
           // $query->sum('quantity');
           $query->select('quantity'); // without `order_id`
       }
])->get();

#=> result:
[{  id: 1,
    code: '00001',
    orderItems: [],    // <== is empty
  },{
    id: 2,
    code: '00002',
    orderItems: [],    // <== is empty
  }...
}]

আছে


Hasমডেলটির বস্তুটি ফিরিয়ে দেবে যে এর সম্পর্ক খালি নয়

Order::has('orderItems')->get();

লারাভেল এই কোডটি একটি এসকিউএল এ পরিবর্তন করুন :

select * from `orders` where exists (
    select * from `order_items` where `order`.`id` = `order_item`.`order_id`
)

whereHas


whereHasএবং আপনার প্রশ্নের উপর শর্ত স্থাপন orWhereHasকরার পদ্ধতি । এই পদ্ধতিগুলি আপনাকে সম্পর্কের সীমাবদ্ধতায় কাস্টমাইজড সীমাবদ্ধতা যুক্ত করতে দেয় ।wherehas

Order::whereHas('orderItems', function($query) {
   $query->where('status', 1);
})->get();

লারাভেল এই কোডটি একটি এসকিউএল এ পরিবর্তন করুন :

select * from `orders` where exists (
    select * 
    from `order_items` 
    where `orders`.`id` = `order_items`.`order_id` and `status` = 1
)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.