🎉 سال نو، مهارت نو، مشاوره رایگان نقشه راه برنامه نویسی (آفر ویژه ثبت نام قبل از افزایش قیمت 🔥)
۰ ثانیه
۰ دقیقه
۰ ساعت
۶ mohammad dadkhah
راهنمایی در مورداکسسور
جامعه لاراول ایجاد شده در ۰۵ بهمن ۱۴۰۰

سلام

اومدید در این مدل product متود زیر تعریف کردید

public function getPriceAttribute($price)
    {
        $coupons = $this->category->validCoupons();
        if ($coupons->isNotEmpty()){
            $discountCalculator = resolve(DiscountCalculator::class);
            return $discountCalculator->discountedPrice($coupons->first() ,$price);
        }
        return $price ;
    }

این خط را در نظر بگیرید

$coupons = $this->category->validCoupons();

حالا این را در نظر بگیرید


namespace App\\Support\\Discount\\Coupon\\Traits;
use App\\Coupon;
use Carbon\\Carbon;
trait Couponable
{
    public function coupons()
    {
        return $this->morphMany(Coupon::class , 'couponable');
    }
    public function validCoupons()
    {
        return $this->coupons->where('expire_time' , '>' , Carbon::now());
    }
}

متود validCoupons

چه طور متوجه می‌شود که مثالا محصول 2 در دسته بندی یک قرار دارد که ایا دسته بندی یک دارای کد تخفیف است یا خیر؟

همان طور که در کد زیر مشاهده می‌کنید اومد یک dd گرفتم


namespace App\\Services\\Traits;
use App\\coupon;
use Carbon\\Carbon;
trait couponable{
    public function coupons()
    {
        return $this->morphMany(coupon::class,'couponable');
    }
    public function validCoupons()
    {
        dd($this->coupons());
       if ( $this->coupons()->where('expire_time','>',carbon::now())) {
        return true;
       };
        return false;
    }
}

و در تصاویر زیر هم محصول با id ، 3 را وارد کردم نتیجه dd را هم در تصویر زیر قرار دادم

توجه شود در کد بالا ،کد استاد در شرط قرار دادم تا بررسی کنم که آیا این خط کد در شرط متوجه می‌شود دسته بندی یک یا دو دارای کد تخفیف است یا نه؟

در اینچا تنها دسته بندی یک دارای کد تخفیف است در حالی این جا هم محصول با دسته بندی یک و هم دو true برگردانده می‌شود.

mohammad dadkhah ۰۵ بهمن ۱۴۰۰، ۰۷:۱۱

سلام محمد عزیز

اگر بصوت خیلی ساده در خصوص اکسسور‌ها باهم بخوایم صحبت کنیم باید خدمت شما عرض کنم که کانسپت لاراول به این صورت کار میکنه که زمانی که شما یک اکسسور ایجاد میکنید استفاده از کسسور در اولیویت قرار میگیره . زمانی که مدل داره اطلاعات رو از دیتا بیس واکشی میکنه تا به صورت یک کالکشن به شما برمیگردونه همه این متود‌ها در پس زمنیه اجرا میشن و لاراول در هنگام ایجا کالکشن مربوطه ، وقتی به یک اکسسور برخودر میکنه متود مربوطه رو پیدا میکنه ومقدار اصلی رو با مقداری که از اکسسور دریافت کرده جابه جا میکنه (getter) همین موضوع برعکس هم داره زمانی که شما یک setter تعریف میکنید در زمان ثبت دارده‌ها هم این اولیوت در دست متود setter هستش تا داده‌های خام .

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

امیدوار هستم که بجواب شمارو کامل داده باشم

محمد نقلانی ۰۵ بهمن ۱۴۰۰، ۰۷:۱۹

سلام مجدد

$this->coupons()

قبول دارم که این

$this

داره به ما دسته بندی محصول را می‌دهد

و وقتی روی آن متود coupons را صدا می‌زنیم باز هم درخروجی اون دسته بندی محصول را نشان می‌دهد که در پست قبل مشاهده کردید

سول دیگه ای که داشتم این که پس این فیلد couponable_id یا couponable_type چه می‌شود؟

mohammad dadkhah ۰۵ بهمن ۱۴۰۰، ۰۷:۳۰

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


در خصوص قسمت دوم سوال ببینید چون شما دارید از روابط پلی مرفیک استفاده میکنید این دوفیل برای شناسایی کلاس‌های مربوط با اون مرفی هستش که شما ایجاد کردید ئ از طریق این دو فیلد کلاس مربوطه شناسایی میشه.

بهترین پاسخ
محمد نقلانی ۰۵ بهمن ۱۴۰۰، ۰۷:۴۸

سلام مجدد

اول ممنونم که وقت می‌گذارید

ببینید اون دو سوال یک گوشه ای نگه دارید

سوال اصلی ام این است که ما در جدول کپن می‌توانیم هم کپن برای یوزر‌ها و هم برای محصولات و هم برای دسته بندی‌ها شون کپن داشته باشیم خب

در این جا استاد از سشن استفاده می‌کنه

namespace App\\Support\\Discount;
use App\\Support\\Cost\\BasketCost;
class DiscountManager
{
    /**
     * @var BasketCost
     */
    private $basketCost;
    /**
     * @var DiscountCalculator
     */
    private $discountCalculator;
    public function __construct(BasketCost $basketCost , DiscountCalculator $discountCalculator)
    {
        $this->basketCost = $basketCost;
        $this->discountCalculator = $discountCalculator;
    }
    public function calculateUserDiscount()
    {
        if (!session()->has('coupon')) return 0 ; 
        return $this->discountCalculator->discountAmount(session()->get('coupon') , $this->basketCost->getTotalCosts());
    }

بنده اطلاعات به جای سشن در پایگاه داده ذخیره می‌کنم حالا می‌خواهم در متود calculatorDiscount اطلاعات را از پایگاه داده دریافت کنم مانند کد بالا و یک پردازش ای انجام بدهم

اسم جدول را session_coupons قرار داده ام و به این شکل عمل کرده ام

?php
namespace App\\Services\\Storage\\Discount;
use App\\Services\\Storage\\Basket\\Basket;
use App\\Services\\Storage\\Cost\\BasketCost;
use App\\Services\\Storage\\Cost\\DiscountCalculator;
use Illuminate\\Support\\Facades\\DB;
class DiscountManager {
    private $discountCalculator;
    private $basketCost;
    public function __construct(BasketCost $basketCost, DiscountCalculator $discountCalculator)
    {
        $this->discountCalculator=$discountCalculator;
        $this->basketCost=$basketCost;
    }
    public function calculateUserDiscount()
    {
      $code=DB::table('session_coupons')->where('user_id',auth('api')->user()->id)->get();
        if (!$code){return 0;}
        return $this->discountCalculator->discountAmount($code,$this->basketCost->getTotalCosts());
    }
}

خب الان یوزر احراز شده دو تا کد تخفیف دارد

الان یک راهنمایی کنید اگه بخواهم از ویژگی اکسسور استفاده کنم چه شکلی می‌شود؟

mohammad dadkhah ۰۵ بهمن ۱۴۰۰، ۰۸:۱۸

سلام مجدد

این شکل ای که بنده الان کد زدم و متوجه شدم

مثال محصول با id 3 هم تخفیف از جاتب یوزر دارد و هم از جانب دسته بندی که درون اش قرار دارد دارای تخفیف است بنده این کد را زدم


namespace App\\Services\\Storage\\Discount;
use App\\Services\\Storage\\Basket\\Basket;
use App\\Services\\Storage\\Cost\\BasketCost;
use App\\Services\\Storage\\Cost\\DiscountCalculator;
use Illuminate\\Support\\Facades\\DB;
class DiscountManager {
    private $discountCalculator;
    private $basketCost;
    public function __construct(BasketCost $basketCost, DiscountCalculator $discountCalculator)
    {
        $this->discountCalculator=$discountCalculator;
        $this->basketCost=$basketCost;
    }
    public function calculateUserDiscount()
    {
      $code=DB::table('session_coupons')->where('user_id',auth('api')->user()->id)->get();
        if (!$code){return 0;}
        return $this->discountCalculator->discountAmount($code,$this->basketCost->getTotalCosts());
    }
}

و بعد

 public function discountAmount($code,int $amount)
    {
      //dd($code);
      $discountAmount=0;
      foreach ($code as $key => $value) {
        $coupon=coupon::where('code',$value->code)->first();
        $discountAmount+=(int)(($coupon->percent/100)*$amount);
      
      };
          
            // $coupon=coupon::where('code',$code->code)->first();
            // $discountAmount=(int)(($coupon->percent/100)*$amount);
        dd($discountAmount);
            return $this->isExceeded($discountAmount,$coupon->limit )?$coupon->limit:$discountAmount;
          
    }

1500 تخفیف از یوزر و 3000 تخفیف از دسته بندی در مجموع 4500

خب الان با روش اول استاد که این شکلی می‌شود خب باید متود isExceeded هم تغییر کنید ونیز یک شرط هم اضافه شود برای این متود

اما اگر بخواهیم از روش دوم استاد که روش اکسسور است استفاده کنیم فرایند کار برای این مثال به مراتب ساده‌تر می‌شود؟

mohammad dadkhah ۰۵ بهمن ۱۴۰۰، ۰۹:۰۸