تزریق نهایی داده‌ها به View و حل مشکلات آن

Final Injection of Data into View

25 بهمن 1399
Laravel 7.0: تزریق نهایی داده ها به view و حل مشکلات آن (قسمت 19)

ما در قسمت قبل از متد find استفاده کردیم و توانستیم کاربر خود را در مرورگر دریافت کنیم:

متد ()dd اجرا شده و داده های درخواست را نشان می دهد
متد ()dd اجرا شده و داده های درخواست را نشان می دهد

از بین این داده های در هم قسمت attributes را باز کنید تا کاربر دریافتی را مشاهده کنید:

قسمت Attribute از درخواست ها
قسمت Attribute از درخواست ها

همانطور که می بینید این همان کاربری است که من ساخته بودم بنابراین همه چیز درست کار می کند. حالا که داده های خود را دریافت کرده ایم، چطور می توانیم آن را به view پاس بدهیم؟ متد view یک آرگومان دوم هم می گیرد که همان داده های پاس داده شده به آن است بنابراین می توانیم داده های دریافت شده از سرور را در یک متغیر ذخیره کرده و آن متغیر را به view مورد نظر ارسال کنیم:

class ProfilesController extends Controller
{
    public function index($user)
    {
        $user = User::find($user);
        return view('home', [
            'user' => $user,
        ]);
    }
}

آرگومان دوم view یک آرایه است که key های آن همان مقداری است که در view در دسترس خواهد بود (من آن را user گذشته ام اما شما می توانید هر نام دیگری برایش انتخاب کنید) و value های آن نیز همان داده هایی است که از سمت پایگاه داده دریافت کرده ایم (متغیر user$). حالا می توانیم به view خودمان رفته و از user استفاده کنیم.

اگر یادتان باشد در php ساده می توانستیم از دستور زیر برای echo کردن داده ها استفاده کنیم:

<?= $user ?>

اما در لاراول از template engine ای به نام blade استفاده می کنیم که تا به حال چندین بار به آن برخورده ایم. به فایل home.blade.php بروید و به جای رشته roxo_ir از blade برای نمایش username استفاده می کنیم:

<div class="col-9 p-5">
    <div>
        <h1>{{ $user->username }}</h1>
    </div>
// بقیه کدها //

نکته: متغیر user$ در اینجا برابر key پاس داده شده به آرگومان دوم view است نه value آن!

همانطور که قبلا هم گفته ام اگر بخواهید کدهای PHP را در فایل های blade اجرا کنیم باید از علامت های {{ }} استفاده نماییم. با این کار محتوای درون {{ }} به عنوان کد در نظر گرفته شده و اجرا خواهد شد. برای تست به آدرس http://127.0.0.1:8000/profile/1 در مرورگر می رویم تا نتیجه را مشاهده کنیم. با این کار به جای roxo_ir (رشته ساده) username خودم را نشان می دهم اما تصاویر بهم می ریزد. می دانید چرا؟ به دلیل اینکه URL را تغییر داده ایم و حالا تصاویر ما می خواهند در آدرس زیر بارگذاری شوند:

http://127.0.0.1:8000/profile/img/first-post.jpg

یعنی قسمت profile به صورت پیشوند به آن ها اضافه شده است. چندین راه حل مختلف برای حل این مشکل وجود دارد. در حال حاضر آدرس دهی به تصاویر برای ما به شکل زیر است که باعث تولید URL بالا می شود:

<img src="img/first-post.jpg" alt="first post" class="w-100">

اما می توانیم یک مرحله به عقب برگردیم:

<img src="../img/first-post.jpg" alt="first post" class="w-100">

با علامت /.. یک مرحله به عقب برگشته و از مسیر پوشه public شروع می کنیم و تصاویر به صورت صحیح بارگذاری می شوند اما اگر دقت کرده باشید این روش خیلی روش جالبی نیست چرا که با هر بار تغییر در URL ها باید لینک تمام تصاویر خود را تغییر دهیم که واقعا آزاردهنده است. روش بهتر استفاده از متد کمکی ()asset است:

<div class="row pt-4">
    <div class="col-4">
        <img src="{{ asset('img/first-post.jpg') }}" alt="first post" class="w-100">
    </div>
    <div class="col-4">
        <img src="{{ asset('img/second-post.jpg') }}" alt="second post" class="w-100">
    </div>
    <div class="col-4">
        <img src="{{ asset('img/third-post.jpg') }}" alt="third post" class="w-100">
    </div>
</div>

این متد به صورت خودکار از پوشه public شروع می کند و پیشوند های URL را در نظر نمی گیرد بنابراین مشکل خود را بدین صورت برطرف کرده ایم. البته باید تصویر پروفایل را نیز تصحیح کنیم:

<div class="col-3 p-5">
    <img class="rounded-circle" src="{{ asset('img/roxo-profile.jpg')}}" alt="roxo profile picture">
</div>

حالا صفحه ما در آدرس http://127.0.0.1:8000/profile/1 به شکل زیر خواهد بود:

تصحیح آدرس تصاویر با متد ()asset
تصحیح آدرس تصاویر با متد ()asset

من از همین روش استفاده می کنم اما روش دیگری نیز وجود دارد. شما می توانید به راحتی در پوشه public خود پوشه دیگری به نام profile ایجاد کنید و سپس در آن پوشه img را داشته باشید. این روش بدترین روش ممکن است چرا که نظم کل پروژه را بهم می ریزد اما می خواستم بدانید که این روش نیز ممکن است.

بدین ترتیب داده ها را در view خود تزریق کرده ایم اما داده های دیگر صفحه چطور؟ مثلا لینک موجود در بیو کاربران یا description آن و تصاویر و غیره؟ من می خواهم برای پروفایل ها یک جدول کاملا جداگانه در پایگاه داده داشته باشم. چرا؟ این کار سلیقه ای است و از نظر من کاربر (user) و پروفایل او (profile) دو مفهوم جدا از هم هستند و نمی خواهم همه چیز را در یک جدول قرار بدهم. اگر این دو را با هم در یک جدول بگذارید کارتان بسیار سخت می شود و همه چیز نظم خود را از دست خواهد داد.

با این حساب باید یک Model جدید بسازیم. چرا؟ به دلیل اینکه هر فایل یا کلاس Model نماینده یک جدول در پایگاه داده است و هر شیء ساخته شده (instance) از کلاس Model نماینده یک ردیف از آن جدول (یک کاربر) است. اگر ما جدول جدیدی می خواهیم باید یک فایل جدید model داشته باشیم. برای این کار در ترمینال می گوییم:

php artisan help make:model

با اجرای این دستور نتیجه زیر را می گیریم (من فقط قسمتی از آن را می آورم):

Description:
  Create a new Eloquent model class

Usage:
  make:model [options] [--] <name>

Arguments:
  name                  The name of the class

این دستور یک کلاس Eloquent (تلفظ: اِلِکوئِنت) می سازد. Eloquent نام لایه ارتباط با پایگاه داده (database layer) در فریم ورک لاراول است. این لایه قدرت بسیار زیادی به ما می دهد. به طور مثال در جلسه قبل دیدید که به جای اجرای یک کوئری کامل SQL از دستور User::find استفاده کردیم تا با پایگاه داده ارتباط برقرار کنیم. یکی از ویژگی های بسیار قوی Eloquent این است که database-agnostic است. یعنی چه؟ یعنی برایش مهم نیست از چه پایگاه داده ای استفاده می کنید بنابراین کوئری هایی که در حال حاضر می نویسیم در MySQL یا sqlite یا MariaDB و غیره کار می کند و نیازی به تغییر چیزی نیست (به جز تعیین نوع پایگاه داده در فایل env.).

یکی از option های موجود و قابل پاس دادن، دستور m- یا migration-- است که به صورت خودکار برای model ما یک migration جدید می سازد. ما به این فایل migration نیاز خواهیم داشت چرا که اگر یک Model جدید بسازیم یعنی یک جدول جدید داریم و برای تعریف ساختار جدول ها در لاراول از migration ها استفاده می کردیم.

در قسمت بعد این دستور را با هم اجرا خواهیم کرد.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری ساخت اینستاگرام با Laravel 7 توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.