سلام وقت بخیر
در یکی از مدل ها تابع زیر را دارم و نیاز هست که مجموع duration ویدئوها کحاسبه بشه.
اما خط ششم درست نیست.
چه کاری باید انجام داد؟
public function topic_duration()
{
$allTopic = $this->hasMany(Topic::class , "workshop_id" , "id");
foreach ($allTopic as $topic) {
$file = File::find($topic->file_id)->first();
$duration += $file->video_duration;
}
return $duration;
}
و از ابتدا با تعریف پروژه شخصی سعی کردم با چالش های مختلف روبه رو بشم و یکی یکی حل کنم.
چالش تمومی نداره. خود پیاچپی رو درست و حسابی یاد بگیرین. مثلاً اینو ببینین:
https://phptherightway.com/
بعدش لاراول رو درست و حسابی یاد بگیرین و داکیومنتیشنش رو بخونین. آموزشهای آقای ایمان غفوری کمنظیره. اگه انگلیسی بلدین که جفریوی ترکونده. بعدش یه دیتابیس رابطهای (MySQL یا PostgreSQL) یاد بگیرین. این رودمپ خیلی خوبه:
https://roadmap.sh/
این یک متد معمولی نیست! این متد در model تعریف شده، متوجه نمیشم چرا گفتید معمولی.
شما یه متد میسازین که قراره یه Relation برگردونه، مثل topic (درستش اینه که بنویسین topics چون one to many هست)، بعضی متدها هم قراره یه مقدار خاصی رو برگردونن و قرار نیست توی این متدهاتون با با مدلهای دیگه ارتباط درست کنین. شما topics رو داشته باشین و داخلش همون Relation رو برگردونین، بعد توی متد getTopicsDuration که درست میکنین...
بیشتر راهنمایی میکنید؟
چرا که نه؟ شما با متد topics یه Relation برمیگردونین و Relation با Collection فرق داره. شما میخوایین به رکوردهای اون یکی جدول دسترسی پیدا کنین، پس کدتون اینطوری میشه:
foreach ($this->topics as $topic) {
.
.
.
وقتی بنویسیم this->topics$ ، یه کالکشن داریم که میشه داخل foreach گذاشت و یکی یکی تاپیکهارو گرفت. البته میشه این جمع رو از طریق دیتابیس انجام داد و دیگه نیازی نیست حلقه نوشت و یکی یکی اضافه کرد.
@mohaligateway
من جاوا اسکریپت زیاد خوندم 😀
بجای + نقطه بزارم یعنی این؟
$duration .= $file->video_duration;
@mohaligateway
مطمعن هستید؟ چون عمل نمیکنه.
در روش خودم و روش شما، زیر $duration خط قرمز کشیده میشود.
شما به خط قرمز IDE کاری نداشته باشید بعضی وقت ها نمی تونه بخونه الان ارور دارید هنگام اجرا کردن کد بالا ؟ ارورش چیه ؟
@msdabbagh
@mohaligateway
@Rp76
کد رو به شکل زیر تغییر دادم و مشکل Undefined variable حل شد.
public function topic_duration()
{
$allTopic = $this->hasMany(Topic::class , "workshop_id" , "id");
$duration = 0;
foreach ($allTopic as $topic) {
$file = File::find($topic->file_id)->first();
$duration .= $file->video_duration;
}
return $duration;
}
اما عدد صفر برمیگرده.
خوب باید جمع بزنید. حالا اون قسمت اول رو که با . نوشتید باید به + تبدیل کنید.
$duration+= $file->video_duration
من میگم نتیجه خط ۶ رو برامون بفرست ببینیم
نتیجه خط ششم هیچی نیست، حتی $topic هم خالیه 🤔
روش دیگه ای برای این کار هست؟ مجموع یک فیلد در رکوردهای file به شرط اینکه اون فایل در topic آمده باشه و اون topic هم زیرمجموعه workshop باشه.
workshop -> topics -> files -> sum filds videoduration
@mohaligateway
چه ربطی به جاواسکریپت داره؟ توی PHP از . برای جوین استفاده میشه ولی + برای جمعه و کار این دوتا فرق داره.
<?php
$num = 12;
$num += 10;
echo $num; // 22
اشتباه شما از اول این بود که =+ رو استفاده کردین. این شکل کوتاهشده x=x+y
هست و کلا برای جمع باید قبلش duration تعریف شده باشه و بعد چیزی باهاش جمع بسته بشه، ولی وقتی هنوز تعریف نشده، مقداری نداره تا یه مقدار دیگه باهاش جمع بشه. اشتباه دوم ریختن قیمه (Relation) توی ماست (متد معمولی که انتظار نمیره رلیشن ایجاد کنه) بوده. اشتباه سوم استفاده مستقیم از Relation بوده، شما نمیتونین Relation رو داخل foreach بذارین، باید با get نتیجه رو به صورت Collection بگیرین.
حدس میزنم دارین از یه سری آموزش ویدئویی استفاده میکنین ولی نمیدونین چرا مدرس فلان کار رو کرده فقط تکرارش میکنین. مفاهیم رو یاد بگیرین و زیاد دنبال آموزش پروژه محور نباشین. باید بدونین رلیشن رو کجا میزنین، چه خروجی داره، چند نوع داره، چرا استفاده میشه، چهطور لاراول هندلش میکنه و الی آخر. اینارو بدونین، میتونین خودتون دوره ضبط کنین و بفرستین ما استفاده کنیم.
@msdabbagh
@muhammad
سلام وقت بخیر
من تنها دوره ای که در مورد لاراول دیدم دوره لاراول راکت هست که در حد احرازهویت و انتشار و مدیریت پست بود.
و از ابتدا با تعریف پروژه شخصی سعی کردم با چالش های مختلف روبه رو بشم و یکی یکی حل کنم.
حالا طبق گفته های شما یک مقدار راهنمایی بیشتر نیاز دارم.
متد معمولی که انتظار نمیره رلیشن ایجاد کنه
این یک متد معمولی نیست! این متد در model تعریف شده، متوجه نمیشم چرا گفتید معمولی.
استفاده مستقیم از Relation بوده، شما نمیتونین Relation رو داخل foreach بذارین، باید با get نتیجه رو به صورت Collection بگیرین.
ما توی همون مدل متد زیر رو به صورت مستقیم ایجاد کردیم و به درستی قابل اجراست.
public function topic()
{
return $this->hasMany(Topic::class , "workshop_id" , "id");
}
و دلیل اینکه در اون قسمت Relation رو داخل foreach گذاشتم این بود که به ازای هر topic فایل متصل به اون رو به دست بیارم.
باید با get نتیجه رو به صورت Collection بگیرین.
بیشتر راهنمایی میکنید؟
و از ابتدا با تعریف پروژه شخصی سعی کردم با چالش های مختلف روبه رو بشم و یکی یکی حل کنم.
چالش تمومی نداره. خود پیاچپی رو درست و حسابی یاد بگیرین. مثلاً اینو ببینین:
https://phptherightway.com/
بعدش لاراول رو درست و حسابی یاد بگیرین و داکیومنتیشنش رو بخونین. آموزشهای آقای ایمان غفوری کمنظیره. اگه انگلیسی بلدین که جفریوی ترکونده. بعدش یه دیتابیس رابطهای (MySQL یا PostgreSQL) یاد بگیرین. این رودمپ خیلی خوبه:
https://roadmap.sh/
این یک متد معمولی نیست! این متد در model تعریف شده، متوجه نمیشم چرا گفتید معمولی.
شما یه متد میسازین که قراره یه Relation برگردونه، مثل topic (درستش اینه که بنویسین topics چون one to many هست)، بعضی متدها هم قراره یه مقدار خاصی رو برگردونن و قرار نیست توی این متدهاتون با با مدلهای دیگه ارتباط درست کنین. شما topics رو داشته باشین و داخلش همون Relation رو برگردونین، بعد توی متد getTopicsDuration که درست میکنین...
بیشتر راهنمایی میکنید؟
چرا که نه؟ شما با متد topics یه Relation برمیگردونین و Relation با Collection فرق داره. شما میخوایین به رکوردهای اون یکی جدول دسترسی پیدا کنین، پس کدتون اینطوری میشه:
foreach ($this->topics as $topic) {
.
.
.
وقتی بنویسیم this->topics$ ، یه کالکشن داریم که میشه داخل foreach گذاشت و یکی یکی تاپیکهارو گرفت. البته میشه این جمع رو از طریق دیتابیس انجام داد و دیگه نیازی نیست حلقه نوشت و یکی یکی اضافه کرد.
@muhammad
ممنونم از معرفی منابع حتما مطالعه میکنم.
طبق روش شما رفتم و فکر میکنم حل شده فقط دیتایی که میگیره رو به عنوان عدد تشخیص نمیده که جمع کنه.
Object of class App\models\File could not be converted to number
or
Object of class App\models\File could not be converted to int
کد من هم به شکل زیر هست
public function topic_duration()
{
$duration = 0;
foreach ($this->topics as $topic) {
$file_duration = File::where('id', $topic->file_id)->get('video_duration')->first();
(int)$duration += (int)$file_duration;
}
return $duration;
}
علتش خیلی واضحه: شما دارین مدل رو جمع میبندین یا کست میکنین به int!
$file_duration = File::where('id', $topic->file_id)->sum('video_duration')
$duration += $file_duration;
البته چنین کدی افتضاح در افتضاحه، چون هر بار یه کوئری به دیتابیس میزنه و یه مدل براش میسازه و مثلا وقتی 50 تا تاپیک داشته باشین، با هر بار استفاده از این متد، 50 تا کوئری میزنه تا یاری که توی خونه هست رو گرد جهان پیدا کنه. راه حلش چیه؟ استفاده از Eager loading، استفاده از دو کوئری یکی برای گرفتن لیستی از آیدی تاپیکها و یکی جمع طول فایلها با WHERE IN، یا استفاده از کوئری SQL خام. بهتر از همهی این راهحلها هم اینه که طول فایلها یه بار برای همیشه محاسبه بشه، چون وقتی قرار نیست طولش تغییر کنه، جالب نیست که هر بار سرور رو اذیت کنیم که یه عدد بهمون بده.
آیا مایل به ارسال نوتیفیکیشن و اخبار از طرف راکت هستید ؟