نمایش داده‌های واقعی در View از پایگاه داده

Displaying Real Data in View From Database

25 بهمن 1399
Laravel 7.0: نمایش داده های واقعی در view از پایگاه داده (قسمت 22)

ما در قسمت قبل روابط جدول ها در سمت پایگاه داده را برای Model هایمان روشن کردیم و حالا نوبت به کدنویسی است. من برای شروع به فایل home.blade.php می روم و داده های جدید و ذخیره شده در سمت سرور را در این view نمایش می دهیم. یادتان باشد که داده ها را با کنترلر در view تزریق کرده بودیم (فایل web.php):

Route::get('/profile/{user}', 'ProfilesController@index')->name('profile.show');

متد index کنترلر نیز کار تزریق داده ها را بر عهده داشت:

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

بنابراین داده های کاربر در متغیری به نام user ذخیره و به view پاس داده می شود (اینها همه یادآوری از جلسات قبل بود). در حال حاضر داده ها به صورت دستی نوشته شده اند:

// بقیه کدها //
<div class="pt-4 font-weight-bold farsi-text">♾️ آکادمی آنلاین روکســـو ♾️</div>
<div class="farsi-text">روکسو یک وبسایت آموزش آنلاین است که در آن هم می‌توانید
    مهارت موردنیازتان را یاد
    بگیرید و هم تخصصِ خود
    را به دیگران یاد بدهید 👇👇
</div>
<div><a href="https://www.roxo.ir/home/" class="font-weight-bold">www.roxo.ir</a></div>
// بقیه کدها //

اما ما می دانیم که به user$ دسترسی داریم بنابراین می توانیم این کار را انجام بدهیم:

<div class="pt-4 font-weight-bold farsi-text">{{ $user->profile->title }}</div>
<div class="farsi-text">{{ $user->profile->description }}</div>
<div><a href="https://www.roxo.ir/home/" class="font-weight-bold">{{ $user->profile->url }}</a></div>

با توجه به توضیحات جلسه قبل فکر نمی کنم نیازی به توضیح اضافه باشد اما در مورد url که null است باید بگویم که لاراول به صورت خودکار مقادیر null در view ها را را برابر یک رشته خالی در نظر می گیرد بنابراین با اینکه href را تعریف کرده ایم اما اصلا چیزی مشاهده نخواهیم کرد. با refresh کردن مرورگر نتیجه زیر را می بینید:

نمایش لینک ما با null از سمت پایگاه داده
نمایش لینک ما با null از سمت پایگاه داده

برای حل مشکل خالی بودن url می توانیم یک مقدار پیش فرض را در نظر بگیریم:

<div><a href="https://www.roxo.ir/home/" class="font-weight-bold">{{ $user->profile->url ?? 'N/A' }}</a></div>

علامت های ؟؟ یعنی اگر url وجود نداشت از رشته N/A استفاده کن (شما می توانید هر رشته دیگری را به جایش بگذارید). N/A مخفف Not Available (به معنی «در دسترس نیست») می باشد. من این مثال را زدم تا شما بدانید چطور می توانیم مقادیر پیش فرض را در blade تعریف کنیم اما این مثال اصلا مثال خوبی نیست و من آن را به حالت قبلی برمی گردانم:

<div><a href="https://www.roxo.ir/home/" class="font-weight-bold">{{ $user->profile->url }}</a></div>

چرا؟ به دلیل اینکه ما href داریم و نشان دادن رشته N/A آن را به یک لینک به نام N/A تبدیل می کند که به آدرس href ما می رود! روش بهتر این است که کدها را به شکل زیر بنویسیم:

<div class="col-9 p-5">
    <div>
        <h1>{{ $user->username }}</h1>
    </div>
    <div class="d-flex">
        <div class="pr-5"><strong>164</strong> posts</div>
        <div class="pr-5"><strong>28k</strong> followers</div>
        <div class="pr-5"><strong>3038</strong> following</div>
    </div>
    <div class="pt-4 font-weight-bold farsi-text">{{ $user->profile->title }}</div>
    <div class="farsi-text">{{ $user->profile->description }}</div>
    @if ($user->profile->url)
    <div><a href="https://www.roxo.ir/home/" class="font-weight-bold">{{ $user->profile->url }}</a></div>
    @else
    <p>No Links Available</p>
    @endif
</div>

یعنی با یک شرط if می گوییم اگر url صحیح بود (null و خالی نبود) لینک را نمایش بده در غیر این صورت یک متن ساده نمایش می دهیم که می گوید No Links Available (هیچ لینکی در دسترس نیست). همچنین من از محیط PHPMyAdmin به جای Cool Title و Description مقادیر قبلی خومان را در پایگاه داده ثبت می کنم تا با refresh کردن صفحه دوباره نتیجه زیر را ببینیم:

داده های واقعی صفحه را از پایگاه داده گرفته و نمایش داده ایم.
داده های واقعی صفحه را از پایگاه داده گرفته و نمایش داده ایم.

اگر از PHPMyAdmin خوشتان نمی آید می توانید وارد محیط Tinker شده و بگویید:

$user = App\User::find(1);
$user->profile->url = 'www.roxo.ir';
$user->push();

در اینجا به جای save باید push را صدا بزنید تا تغییرات شما در پایگاه داده اعمال شود. save در اینجا فقط رابطه را ذخیره می کند و اثری روی پایگاه داده ندارد.

حالا که صفحه را به درستی نمایش می دهیم باید یکی از مشکلات فعلی برنامه را نیز حل کنیم. ما id کاربر را از URL مرورگر گرفته و در پایگاه داده جست و جو می کنیم بنابراین اگر id را وارد کنیم که وجود نداشته باشد چه می شود؟ برای تست به یکی از آدرس های زیر بروید (یا هر آدرسی که id آن در پایگاه داده نباشد):

http://127.0.0.1:8000/profile/2
http://127.0.0.1:8000/profile/roxo.ir
http://127.0.0.1:8000/profile/aslifhsadasfhihlih232394u

با ورود به هر صفحه ای که id آن (قسمت آخر URL - اگر یادتان رفته به فایل web.php مراجعه کنید) وجود نداشته باشد، تمام برنامه متوقف شده و خطا می گیریم. برای حل این مشکل باید به ProfileController.php برویم و به جای find از دستور findOrFail استفاده کنیم:

public function index($user)
{
    $user = User::findOrFail($user);
    return view('home', [
        'user' => $user,
    ]);
}

با این کار اگر مقدار وارد شده در URL در پایگاه داده وجود نداشته باشد یک صفحه 404 می گیریم. می توانید این مسئله را با رفتن به صفحه ای غیر مجاز مثل صفحه http://127.0.0.1:8000/profile/847832479327489327 تست کنید. باید برایتان یک خطای 404 نمایش داده شود.

مسئله بعدی این است که ما علاوه بر کاربر و پروفایل، مفهوم پست ها را نیز داریم که یک فایل Model دیگر و یک جدول دیگر می خواهد. این relation با relation قبلی تفاوت بزرگی دارد. در relation قبلی گفتیم که هر کاربر یک پروفایل داشته و هر پروفایل متعلق به یک کاربر است بنابراین رابطه ما از نوع یک به یک (one to one relationship) است اما رابطه بین کاربر و پست های او اینطور نیست. هر کاربر چندین پست خواهد داشت و تمام پست ها متعلق به یک کاربر خواهند بود بنابراین رابطه ما از نوع یک به چند (One to Many Relationship) می باشد.

ما در جلسه بعد وارد این موضوع خواهیم شد اما اگر می خواهید در این مورد بیشتر مطالعه کنید، پیشنهاد می کنم سری به Documentation رسمی لاراول در این مورد بزنید:

https://laravel.com/docs/7.x/eloquent-relationships#one-to-many

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

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