رتبه موضوع:
  • 0 رای - 0 میانگین
  • 1
  • 2
  • 3
  • 4
  • 5
نمایش پستها با نویسنده آن
#1
درود
فرض کنید من میخوام پست های وبلاگم رو به همراه نویسندش نمایش بدم.یک جدول پست دارم ویک فیلد داره به نام user_id که با جدول user ریلیشن میشن.
پرسش من اینجاست که چجوری پستها رو با نام نویسنده پست چاپ کنم؟
اینجوری نمیشه
Post::find(1)->user

چون شاید کاربر ۲۰ پست ۱ رو ساخته باشه.
ممنون میشم راهنماییم کنید؟
پاسخ
تشکر شده توسط:
#2
دقیقاً به فارسی بگین چی میخواین تا کد معادلش رو بگیم:
  • میخواین تمام پستها + نویسنده اونها رو نشون بدین؟
  • پستهای یک کاربر خاص رو نشون بدین؟
  • کاربری که یک پست خاص رو گذاشته نشون بدین؟
پاسخ
تشکر شده توسط:
#3
خدایی فارسی نبود؟
پست های وبلاگم رو به همراه نویسندش
پاسخ
تشکر شده توسط:
#4
foreach(Post::all() as $post) {
    echo $post->user->name;
}
پاسخ
تشکر شده توسط: Mohammadsgh
#5
باید از inner join استفاده کنید
    $posts = DB::table('users')
                ->join('posts', 'users.id', '=', 'posts.user_id')
                ->select('users.name', 'posts.*')
                ->get();

کد بالا معادل کوئری زیر هست :
select `users`.`name`, `posts`.* from `users` inner join `posts` on `users`.`id` = `posts`.`user_id`

تو ویو هم میتونید هم به تمام ستون های پست و ستون نام کاربر نویسنده دسترسی داشته باشید
    @foreach($posts as $post)
        <p>title : {{ $post->title }}</p>
        <p>body : {{ $post->body }}</p>
        <p>author: {{ $post->name }}</p>
        <hr>
    @endforeach
موفقیت، نتیجه تشخیص درست است؛ تشخیص درست، نتیجه تجربه است؛ تجربه نیز اغلب نتیجه تشخیص نادرست است.



پاسخ
تشکر شده توسط: meysam1366
#6
مگه وقتی ریلیشن زدیم خودش ساب کوئری نمیزنه؟
پاسخ
تشکر شده توسط:
#7
دستوری که در مستندات هست برای حالتی هست که قراره تمام پست های یک کاربر با آیدی مورنظرو در بیاریم ولی برای این حالت که تمام پست ها قراره بازیابی بشه باید join بزنند مشابه اون در eloquent هم به این صورته :
$posts = App\Post::join('users', function($join){
        $join->on('users.id', '=', 'posts.user_id');
    })->select('users.name', 'posts.*')->get();
موفقیت، نتیجه تشخیص درست است؛ تشخیص درست، نتیجه تجربه است؛ تجربه نیز اغلب نتیجه تشخیص نادرست است.



پاسخ
تشکر شده توسط:
#8
خوب این که زیاد جالب نیست. برای مثال، توی Yii وقتی میگیم ریلیشن تعریف کردیم و گفتیم مثلاً ارتباط belongsTo داره با جدول User ازطریق فیلد user_id ، وقتی میگیم post->user$ خودش میره یه کوئری میزنه به جدول User و رکوردی که id اون با user_id اینطرف هست رو پیدا میکنه و اگه با with صدا بزنیم و together رو true کنیم، همون موقع Join میزنه. دیگه لازم نیست دستی جوین بزنیم. اگه قرار بود جوین بزنیم پس ریلیشن رو واسه چی تعریف کردیم؟

بطور مشابه، وقتی توی مدل User میایم یه ریلیشن hasMany با جدول Post برقرار میکنیم، وقتی میگیم user->posts$ خودش میره کوئری میزنه و تمام پستهای اون کاربر رو استخراج میکنه. مطمئناً لاراول هم رفتار مشابهی داره وگرنه Relationها عملاً بلا استفاده میشن.
پاسخ
تشکر شده توسط:
#9
قطعا در Eloquent هم می توان به مانند ActiveRecord در Yii عمل کرد. چون ایشون کدی اینجا قرار ندادن و هیچ اشاره ای به تعریف relation در مدل هاشون نکردن من این روش رو پیشنهاد دادم تا فورا نتیجه بگیرند.

اگر از hasMany و belongsTo در مدل هاشون استفاده کردن به این طریق می توانند به تمام پست ها به همراه نویسنده هاشون دسترسی داشته باشند :
$posts = Post::with('User')->get();

نحوه دسترسی در ویو :
    @foreach($posts as $post)
        <h2>{{ $post->title }}</h2>
        <p>{{ $post->body }}</p>
        <p>{{ $post->user->name }}</p>
        <hr>
    @endforeach
موفقیت، نتیجه تشخیص درست است؛ تشخیص درست، نتیجه تجربه است؛ تجربه نیز اغلب نتیجه تشخیص نادرست است.



پاسخ
تشکر شده توسط: ADMIN , Renegad , meysam1366
#10
راستی یادم رفت مهندس روشی که شما هم ذکر کردین Post::all() هم کار میکنه اما باعث ایجاد مشکل N+1 در لاراول میشه و Eager loading که من در بالا مثالشو زدم راه حلشه
موفقیت، نتیجه تشخیص درست است؛ تشخیص درست، نتیجه تجربه است؛ تجربه نیز اغلب نتیجه تشخیص نادرست است.



پاسخ
تشکر شده توسط: ADMIN , Renegad , meysam1366
#11
راستش من زیاد لاراول کار نکردم و این مثال رو هم از توی مستندات خودش پیدا کردم. این مشکل N+1 توی Yii هم هست و راه حل اونجا هم همین Eager Loading هست که البته با کمک فعال کردن together میشه فریمورک رو وادار کرد حتماً Join بزنه و از SubQuery استفاده نکنه. یادمه قبلاً توی لاراول خودش Join نمیزد و باید دستی Join میزدیم. منظورم اینه که با کمک with بازم SubQuery میزنه. حقیقتش اگه ابزاری که باهاش کار میکنیم رو به خوبی بشناسیم، خیلی بهتر میشه ازش استفاده کنیم. به استارتر شدیداً مطالعه مستندات رو توصیه میکنم. با توجه به علاقه زیادشون به لاراول و ازطرفی روحیه ای که ازشون میشناسم، اگه نتونن به خوبی از امکانات این فریمورک قدرتمند استفاده کنن، ممکنه ازش دلسرد بشن.
پاسخ
تشکر شده توسط: hamo , Renegad , meysam1366




کاربران در حال بازدید این موضوع: 1 مهمان