سلام به همگی
من میخام سیستم امتیاز دهی کنار هر محصول قرار بدم
دیتابیس و ارتباط درست کردم
برای ویو نمیدونم چیکار کنم که تو دیتابیس ذخیره بشه
دیتابیس
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>
سلام یک فرم ایجاد می کنید کاربر rating و review خودش رو وارد می کنه رو دکمه ثبت میزنه id کاربر رو از session هامی گیرید و id محصول رو از روت. بعد هم ذخیره می کنید.
@websaz
الان کدهای بالا کدوم قسمت اشتباهه ؟
با سشن فقط کار میکنه ؟
من نمیخام برای کامنت باشه امتیاز دهی
میخام ۵ تا ستاره باشه کنار محصول
که کاربر رو هر کدوم کلیک کرد اطلاعات تو دیتابیس ذخیره بشه
می خواهید به صورت ajax ارسال کنید؟
شما در فرم باید product_id رو به صورت hidden قرار بدید.
@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 درخواست فرستاده بشه؟
سلام من یه نمونه کد بهت میدم درباره امتیاز دهی دیدگاهای یک ویدیو هست شاید کمکت کنه تا بتونی درخواست ایجکس رو بفرستی.
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');
@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'),
]);
}
}
}
اگه چیزی تو دیتابیس ذخیره نمیشه شاید به این دلیل باشه که درخواستت وارد کنترلر نمیشه چون با ایجکس میفرستی تو تب network مرورگر زبانه xhr چک کن ببین اروری نداری.
بعد هم اینکه چون با ایجکس میفرستی دیگه فرم نیاز نیست
@hosseinshirinegad98
اها درسته فرم پاک کردم
روت مشکلی نداره؟
شایدم کنترلر اشتباه انجام دادم نمیدونم
Route::post('rate/{product}', 'RatingController@store')->name('rating');
اروری هم ندارم تو این زبانه
روت نه
ولی ارسال درخواست با ایجکس شاید مشکل داره باید روتتو تو ایجکس جایگزین کنی
شاید هم کنترلرت مشکل داره بعد اینکه درخواستو با ایجکس میفرستی قدم به قدم از کدها خروجی بگیر
هر بار که درخواستی میفرستی تو زبانه network خطایی بود باید بهت نشون داده بشه
تبnetwork و xhr رو باز کن و بعد اقدام به ثبت امتیاز کن اینطوری خطارو بهت با همونجا با یه شماره قرمز رنگ نشون میده روش کلبک کنی جزئیات خطارو بهت میده
@hosseinshirinegad98
الان تازه داره یک ارور نمایش میده
روش کلیک کردم این مورد نمایش داده شد
Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
The GET method is not supported for this route. Supported methods: POST.
http://localhost:8000/rate/27
ببینید یه اشتباه که میتونه داشته باشید اینه در متد store پارامتر اول باید FormRequest باشه پارامتر دوم میشه product
شما برعکسشو نوشتید
@hosseinshirinegad98
اسم پارامتر رو هم درست کردم
این اروری که میده برای خود ajax نیست ؟
از این صفحه ارور میده وقتی روش کلیک میکنم یا اعتبار سنجیه نمیدونم
اعتبار سنجی خطا بده کدش 422 هست
شاید کتابخونه jquery به برنامت پیوست نشده.
کد ایجکست که درخواستو ارسال میکنه اینجا قرارش بده ببینم چیکارش کردی.
گفته باشم کدهای کنترلرت کاملاباید با جدول ها و ریلیشن های برنامت هماهنگ و همخونی داشته باشه
نکنه فیلدی یا ریلیشنی تو کدت که من بهت دادم باشه که تو جدول یا مدلهات تعریف نشده باشه
مدام برگهnetworkو xhrرو تو هر درخواست برسی کن اونجا ارورو بهت میده میتونی برطرفش کنی.
@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)"
تو تعریف مدل ها مشکل هست درسته ؟
آیا مایل به ارسال نوتیفیکیشن و اخبار از طرف راکت هستید ؟