راکت

امتیاز به محصول

16 پاسخ

سلام به همگی
من میخام سیستم امتیاز دهی کنار هر محصول قرار بدم
دیتابیس و ارتباط درست کردم
برای ویو نمیدونم چیکار کنم که تو دیتابیس ذخیره بشه

دیتابیس

        Schema::create('rates', function (Blueprint $table) {
           $table->id();

           $table->foreignId('product_id')
                ->constrained()
                ->onUpdate('CASCADE')
                ->onDelete('CASCADE');
            $table->foreignId('user_id')
                ->constrained()
                ->onUpdate('CASCADE')
                ->onDelete('CASCADE');

            $table->integer('rating');
            $table->timestamps();
        });

روت

Route::post('/rate/{product:slug}', 'RatingController@store')->name('rate.product');

کنترلر

    public function store(Product $product , Request $request)
    {
       $validData = $request->validate([
            'rating' => '',
        ]);

        $product = auth()->user()->rates()->create($request->all());

        alert()->success('امتیاز مورد نظر با موفقیت ثبت شد' , 'با تشکر');

        return redirect(route('rate.product'));
    }

مدل پروداکت


    public function rates()
    {
        return $this->belongsToMany(Rate::class);
    }

مدل rate


class Rate extends Model
{

    protected $fillable = [
        'product_id', 'user_id', 'rating' ,
    ];

   public function Products()
    {
        return $this->belongsToMany(Product::class);
    }
}

مدل یوزر

    public function rates()
    {
        return $this->hasMany(Rate::class);
    }

ویو امتیاز
اینجا تو قسمت value نمیدونم چی بزارم
و قسمتی که کلاس fontawsome هست رو باید داینامیک کنم نمیدونم به چه صورت

                                                        <fieldset class="rating"> 

                                        @for ($i = 0; $i < 5; $i++)

                                        <input type="radio" id="star5" name="rating[]" value="" />
                                        <label class="full" for="star5" title="Awesome - 5 stars">
                                        </label> 

                                          @endfor

                                    </fieldset>

<script>
$("#input-id").rating();

$("#input-id").rating({'size':'lg'});

</script>
ثبت پرسش جدید

پاسخ‌ها

16
Paradox
Paradox
@paradox

تخصص: در حال یادگیری

دوستان کسی میتونه راهنمای کنه ؟

سبحان مولایی
سبحان مولایی
@websaz

تخصص: برنامه‌نویس وب: Python :: Django :: Node :: Php :: Laravel :: JS :: React :: React Native

سلام یک فرم ایجاد می کنید کاربر rating و review خودش رو وارد می کنه رو دکمه ثبت میزنه id کاربر رو از session هامی گیرید و id محصول رو از روت. بعد هم ذخیره می کنید.

شاید پاسخ شما همین‌جا باشد

Paradox
Paradox
@paradox

تخصص: در حال یادگیری

@websaz
الان کدهای بالا کدوم قسمت اشتباهه ؟
با سشن فقط کار میکنه ؟
من نمیخام برای کامنت باشه امتیاز دهی
میخام ۵ تا ستاره باشه کنار محصول
که کاربر رو هر کدوم کلیک کرد اطلاعات تو دیتابیس ذخیره بشه

سبحان مولایی
سبحان مولایی
@websaz

تخصص: برنامه‌نویس وب: Python :: Django :: Node :: Php :: Laravel :: JS :: React :: React Native

می خواهید به صورت ajax ارسال کنید؟
شما در فرم باید product_id رو به صورت hidden قرار بدید.

Paradox
Paradox
@paradox

تخصص: در حال یادگیری

@websaz
ajax کار نکردم
پس باید به شکل ajax باشه ؟
من 5 تا ستاره دارم مثل عکس زیر
ستاره
فرمم اینه input فرمودید اضافه کردم درسته ؟ روت هم درست تعریف شد؟

                            <div class="">
                                <form action="{{ route('rating', ['product' => $product->slug]) }}" method="POST">
                                    <fieldset class="rating"> 

                                        @for ($i = 0; $i < 5; $i++)

                                        <input type="hidden" name="product_id">

                                        <input type="radio" id="star5" name="rating[]" value="" />
                                        <label class="full" for="star5" title="Awesome - 5 stars">
                                        </label> 

                                          @endfor

                                    </fieldset>
                                 </form>
                                </div>

روت

Route::post('/rate/{product:slug}', 'RatingController@store')->name('rating');

مشکل اول رو 3 تا ستاره هم اگه بزنم هر 5 تا انتخاب میشه
مشکل دوم چیزی تو دیتابیس ذخیره نمیشه و نمیدونم چطوری درخواست سمت دیتابیس بفرستم
باید به شکل ajax درخواست فرستاده بشه؟

حسین شیری نژاد
حسین شیری نژاد
@hosseinshirinegad98

تخصص: programmer

سلام من یه نمونه کد بهت میدم درباره امتیاز دهی دیدگاهای یک ویدیو هست شاید کمکت کنه تا بتونی درخواست ایجکس رو بفرستی.

 Route::post('score/{comment}', [ScoreController::class, 'store'])->name('comment.score.store');
    public function store(ScoreRequest $request, Comment $comment)
    {
        if ( $request->ajax() ) {
            $data = $request->validated();

            $user = Auth::user();

            $score = !! $comment->scores()->where('user_id', $user->id)->first();

            if (! $score) {
                try {
                    $score = new Score;

                    $score->user_id = $user->id;

                    $score->score = $data['score'];

                    try {
                        $comment->scores()->save($score);
                    } catch (\Throwable $th) {
                        alert()->error('', 'خطایی پیش آمده ، لطفا دوبار سعی نمایید');

                        return back();
                    }

                    $video =  $comment->video;

                    $video->num_score += 1;

                    $video->sum_score += $data['score'];

                    $video->average_score = floor(($video->sum_score / $video->num_score) * 2) / 2;

                    $video->save();
                } catch (\Throwable $th) {
                    alert()->error('', 'خطایی پیش آمده ، لطفا دوبار سعی نمایید');

                    return back();
                }
            }

            return view('user.ajax.score', [
                'video' => $video->load('comments'),
            ]);
        }
    }
                        <fieldset class="rating rating-a">
                            <input type="radio" id="star5" name="rating" value="5"/>
                            <label class="full star" data-score="5" data-url="{{route('comment.score.store', $comment->id)}}" for="star5" title="5 "></label>
                            <input type="radio" id="star4half" name="rating" value="4 and a half" />
                            <label class="half star" data-score="4.5" data-url="{{route('comment.score.store', $comment->id)}}" for="star4half" title=" 4.5 "></label>
                            <input type="radio" id="star4" name="rating" value="4" />
                            <label class="full star" data-score="4" data-url="{{route('comment.score.store', $comment->id)}}" for="star4" title="4 "></label>
                            <input type="radio" id="star3half" name="rating" value="3 and a half"/>
                            <label class="half star" data-score="3.5" data-url="{{route('comment.score.store', $comment->id)}}" for="star3half" title="3.5"></label>
                            <input type="radio" id="star3" name="rating" value="3"/>
                            <label class="full star" data-score="3" data-url="{{route('comment.score.store', $comment->id)}}" for="star3" title="3"></label>
                            <input type="radio" id="star2half" name="rating" value="2 and a half" />
                            <label class="half star" data-score="2.5" data-url="{{route('comment.score.store', $comment->id)}}" for="star2half" title=" 2.5"></label>
                            <input type="radio" id="star2" name="rating" value="2" />
                            <label class="full star" data-score="2" data-url="{{route('comment.score.store', $comment->id)}}" for="star2" title="2"></label>
                            <input type="radio" id="star1half" name="rating" value="1 and a half" />
                            <label class="half star" data-score="1.5" data-url="{{route('comment.score.store', $comment->id)}}" for="star1half" title="1.5"></label>
                            <input type="radio" id="star1" name="rating" value="1" />
                            <label class="full star" data-score="1" data-url="{{route('comment.score.store', $comment->id)}}" for="star1" title="1"></label>
                            <input type="radio" id="starhalf" name="rating" value="half" />
                            <label class="half star" data-score="0.5" data-url="{{route('comment.score.store', $comment->id)}}" for="starhalf" title="0.5"></label>
                        </fieldset>
/**
 * send ajax request for store score for comment
 */
$('.star').click(function() {
    const url = $(this).data('url');
    const score = $(this).data('score');

    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });

    $.ajax({
        url,
        type: "POST",
        data: {
            score,
        },
        success: function (data) {
            $('#show-scores').html(data);

        },
        error: function(e) {
            $.toast({
                heading: 'خطا',
                text: 'برای ثبت امتیاز باید وارد سایت شوید',
                showHideTransition: 'slide',
                icon: 'warning'
            });
        }
    });
});

نمایش امتیاز بعد از هر با ثبت امتیاز با ایجکس فایل user.ajax.score

<fieldset class="rating">
    <input type="radio" id="star5" name="rating" value="5" @if( $video->average_score == 5 ) checked  @endif/>
    <label class="full" for="star5" title="5 "></label>
    <input type="radio" id="star4half" name="rating" value="4 and a half" @if( $video->average_score == 4.5 ) checked  @endif/>
    <label class="half" for="star4half" title=" 4.5 "></label>
    <input type="radio" id="star4" name="rating" value="4" @if( $video->average_score == 4 ) checked  @endif/>
    <label class="full" for="star4" title="4 "></label>
    <input type="radio" id="star3half" name="rating" value="3 and a half" @if( $video->average_score == 3.5 ) checked  @endif/>
    <label class="half" for="star3half" title="3.5"></label>
    <input type="radio" id="star3" name="rating" value="3" @if( $video->average_score == 3 ) checked  @endif/>
    <label class="full" for="star3" title="3"></label>
    <input type="radio" id="star2half" name="rating" value="2 and a half" @if( $video->average_score == 2.5 ) checked  @endif/>
    <label class="half" for="star2half" title=" 2.5"></label>
    <input type="radio" id="star2" name="rating" value="2" @if( $video->average_score == 2 ) checked  @endif/>
    <label class="full" for="star2" title="2"></label>
    <input type="radio" id="star1half" name="rating" value="1 and a half" @if( $video->average_score == 1.5 ) checked  @endif/>
    <label class="half" for="star1half" title="1.5"></label>
    <input type="radio" id="star1" name="rating" value="1" @if( $video->average_score == 1 ) checked  @endif/>
    <label class="full" for="star1" title="1"></label>
    <input type="radio" id="starhalf" name="rating" value="half" @if( $video->average_score == 0.5 ) checked  @endif/>
    <label class="half" for="starhalf" title="0.5"></label>
</fieldset>

این سه تا فیلدو به جدول محصولاتت باید اضافه کنی من به جدول ویدیوها اضافه کردم که امتیاز هر محصول کنارش باشه نه اینکه با ریلیشن بدستش بیاری
با ریلیشن فقط برسی میکنی که کاربر مجاز به امتیاز دادن هست یا نه.

            $table->integer('num_score')->default(0);

            $table->float('sum_score')->default(0);

            $table->float('average_score')->default(0);`کد خود را اینجا وارد کنید`

اینم جدول امتیازها

            $table->foreignId('comment_id')->constrained()->onDelete('cascade');
            $table->foreignId('user_id')->constrained()->onDelete('cascade');
            $table->smallInteger('score');
Paradox
Paradox
@paradox

تخصص: در حال یادگیری

@hosseinshirinegad98
سلام ممنونم جداول درست کردم
ویو امتیازات و کنترلر به این شکل هست مشکل اولی که داشتم حل شد
فقط هنوز تو دیتابیس چیزی ذخیره نمیشه

                         <form action="{{ route('rating', ['product' => $product->id]) }}" method="POST">
                          <fieldset class="rating rating-a">

                            <input type="radio" id="star5" name="rating" value="5"/>
                            <label class="full star" data-score="5" data-url="{{route('rating', $product->id)}}" for="star5" title="5 "></label>

                            <input type="radio" id="star4" name="rating" value="4" />
                            <label class="full star" data-score="4" data-url="{{route('rating', $product->id)}}" for="star4" title="4 "></label>

                            <input type="radio" id="star3" name="rating" value="3"/>
                            <label class="full star" data-score="3" data-url="{{route('rating', $product->id)}}" for="star3" title="3"></label>

                            <input type="radio" id="star2" name="rating" value="2" />
                            <label class="full star" data-score="2" data-url="{{route('rating', $product->id)}}" for="star2" title="2"></label>

                            <input type="radio" id="star1" name="rating" value="1" />
                            <label class="full star" data-score="1" data-url="{{route('rating', $product->id)}}" for="star1" title="1"></label>

                        </fieldset>
                        </form>

کنترلر امتیازات


class RatingController extends Controller
{
    public function store(Product $product , Request $request)
    {
    if ( $request->ajax() ) {
            $data = $request->validated();

            $user = Auth::user();

            $rate = !! $product->rates()->where('user_id', $user->id)->first();

            if (! $rate) {
                try {
                    $rate = new Rate;

                    $rate->user_id = $user->id;

                    $rate->rate = $data['rate'];

                    try {
                        $product->rates()->save($rate);
                    } catch (\Throwable $th) {
                        alert()->error('', 'خطایی پیش آمده ، لطفا دوبار سعی نمایید');

                        return back();
                    }

                    $rate =  $product->rate;

                    $product->num_score += 1;

                    $product->sum_score += $data['rate'];

                    $product->average_score = floor(($product->sum_score / $product->num_score) * 2) / 2;

                    $product->save();
                } catch (\Throwable $th) {
                    alert()->error('', 'خطایی پیش آمده ، لطفا دوبار سعی نمایید');

                    return back();
                }
            }

            return view('user.ajax.score', [
                'product' => $product->load('rates'),
            ]);
        }
    }
}
حسین شیری نژاد
حسین شیری نژاد
@hosseinshirinegad98

تخصص: programmer

اگه چیزی تو دیتابیس ذخیره نمیشه شاید به این دلیل باشه که درخواستت وارد کنترلر نمیشه چون با ایجکس میفرستی تو تب network مرورگر زبانه xhr چک کن ببین اروری نداری.
بعد هم اینکه چون با ایجکس میفرستی دیگه فرم نیاز نیست

Paradox
Paradox
@paradox

تخصص: در حال یادگیری

@hosseinshirinegad98
اها درسته فرم پاک کردم
روت مشکلی نداره؟
شایدم کنترلر اشتباه انجام دادم نمیدونم

Route::post('rate/{product}', 'RatingController@store')->name('rating');

اروری هم ندارم تو این زبانه
xhr

حسین شیری نژاد
حسین شیری نژاد
@hosseinshirinegad98

تخصص: programmer

روت نه
ولی ارسال درخواست با ایجکس شاید مشکل داره باید روتتو تو ایجکس جایگزین کنی
شاید هم کنترلرت مشکل داره بعد اینکه درخواستو با ایجکس میفرستی قدم به قدم از کدها خروجی بگیر
هر بار که درخواستی میفرستی تو زبانه network خطایی بود باید بهت نشون داده بشه
تبnetwork و xhr رو باز کن و بعد اقدام به ثبت امتیاز کن اینطوری خطارو بهت با همونجا با یه شماره قرمز رنگ نشون میده روش کلبک کنی جزئیات خطارو بهت میده

Paradox
Paradox
@paradox

تخصص: در حال یادگیری

@hosseinshirinegad98
الان تازه داره یک ارور نمایش میده
ارور

روش کلیک کردم این مورد نمایش داده شد

Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
The GET method is not supported for this route. Supported methods: POST.
http://localhost:8000/rate/27

ارور2

حسین شیری نژاد
حسین شیری نژاد
@hosseinshirinegad98

تخصص: programmer

ببینید یه اشتباه که میتونه داشته باشید اینه در متد store پارامتر اول باید FormRequest باشه پارامتر دوم میشه product
شما برعکسشو نوشتید

Paradox
Paradox
@paradox

تخصص: در حال یادگیری

@hosseinshirinegad98
اسم پارامتر رو هم درست کردم
این اروری که میده برای خود ajax نیست ؟
از این صفحه ارور میده وقتی روش کلیک میکنم یا اعتبار سنجیه نمیدونم

ارور

حسین شیری نژاد
حسین شیری نژاد
@hosseinshirinegad98

تخصص: programmer

اعتبار سنجی خطا بده کدش 422 هست
شاید کتابخونه jquery به برنامت پیوست نشده.
کد ایجکست که درخواستو ارسال میکنه اینجا قرارش بده ببینم چیکارش کردی.
گفته باشم کدهای کنترلرت کاملاباید با جدول ها و ریلیشن های برنامت هماهنگ و همخونی داشته باشه
نکنه فیلدی یا ریلیشنی تو کدت که من بهت دادم باشه که تو جدول یا مدلهات تعریف نشده باشه
مدام برگهnetworkو xhrرو تو هر درخواست برسی کن اونجا ارورو بهت میده میتونی برطرفش کنی.

Paradox
Paradox
@paradox

تخصص: در حال یادگیری

@hosseinshirinegad98
ajax


/**
 * send ajax request for store score for comment
 */
$('.star').click(function() {
    const url = $(this).data('url');
    const score = $(this).data('score');

    $.ajaxSetup({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        }
    });

    $.ajax({
        url,
        type: "POST",
        data: {
            score,
        },
        success: function (data) {
            $('#show-scores').html(data);

        },
        error: function(e) {
            $.toast({
                heading: 'خطا',
                text: 'برای ثبت امتیاز باید وارد سایت شوید',
                showHideTransition: 'slide',
                icon: 'warning'
            });
        }
    });
});

کنترلر

    public function store(Request $request , Product $product)
    {
    if ( $request->ajax() ) {

            $data = $request->all();

            $rate = !! $product->rates()->where('user_id', auth()->id())->first();

            if (! $rate) {
                try {
                    $rate = new Rate;

                    $rate->user_id = auth()->id();

                    $rate->rate = $data['rate'];

                    try {
                        $product->rates()->save($rate);
                    } catch (\Throwable $th) {
                        alert()->error('', 'خطایی پیش آمده ، لطفا دوبار سعی نمایید');

                        return back();
                    }

                    $rate =  $product->rate;

                    $product->save();
                } catch (\Throwable $th) {
                    alert()->error('', 'خطایی پیش آمده ، لطفا دوبار سعی نمایید');

                    return back();
                }
            }

            return view('user.ajax.score', [
                'product' => $product->load('rates'),
            ]);
        }
    }

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

        Schema::create('rates', function (Blueprint $table) {
           $table->id();
           $table->foreignId('product_id')->constrained()->onDelete('cascade');
           $table->foreignId('user_id')->constrained()->onDelete('cascade');
           $table->integer('rating');
           $table->timestamps();
        });

مدل rate

      public function Products()
    {
        return $this->hasMany(Product::class , 'product_rate' , 'product_id');
    }

مدل user

         public function rates()
    {
        return $this->hasMany(Rate::class , 'rate_user');
    }

مدل product

         public function rates()
    {
        return $this->hasMany(Rate::class , 'product_rate' , 'product_id');
    }

حالا اروری که دارم

message: "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'rates.product_rate' in 'where clause' (SQL: select * from `rates` where `rates`.`product_rate` is null and `rates`.`product_rate` is not null and `user_id` = 2 limit 1)"

تو تعریف مدل ها مشکل هست درسته ؟

Paradox
Paradox
@paradox

تخصص: در حال یادگیری

@hosseinshirinegad98
ثبت شد تو دیتابیس ولی چیزی تو ویو نمایش نمیده

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

ورود یا ثبت‌نام