在laravel中将值返回null

时间:2017-10-18 06:40:45

标签: php sql laravel

我正在使用Laravel 5.5从事电子商务项目,在我的产品表中,我有2列名为discountdiscount_date,我想要的是列{{1}的日期1}} discount_datediscount列自动变为空。

我该怎么做?

更新

ProductController的:

discount_date

更新2 <?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Product; use App\Subcategory; use App\Category; use App\Attribute; use Carbon\Carbon; use App\User; use Auth; use DB; use Storage; use Spatie\Permission\Models\Role; use Spatie\Permission\Models\Permission; use jpmurray\LaravelCountdown\Countdown; class ProductController extends Controller { public function __construct() { $this->middleware(['auth', 'isAdmin']); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { $products = Product::orderby('id', 'desc')->get(); return view('admin.products.index', compact('products')); } public function show($slug) { $product = Product::where('slug', $slug)->firstOrFail(); $countdown = DB::table('products')->where('discount_date', '!=', null)->pluck('discount_date'); $now = Carbon::now(); return view('admin.products.show', compact('product', 'countdown', 'now')); } public function create() { $categories = Category::all(); $subcategories = Subcategory::all(); $attributes = Attribute::all(); $user = Auth::user(); return view('admin.products.create', compact('user', 'categories', 'subcategories', 'attributes')); } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { //Validating title and body field $this->validate($request, array( 'title'=>'required|max:225', 'slug' =>'required|max:255|unique:products', 'user_id' =>'required|numeric', 'image_one' =>'nullable|image', 'image_two' =>'nullable|image', 'image_three' =>'nullable|image', 'image_four' =>'nullable|image', 'short_description' => 'nullable|max:1000', 'description' => 'required|max:100000', 'subcategory_id' => 'required|numeric', 'discount' => 'nullable|numeric', 'discount_date' => 'nullable|date', 'price' => 'required|numeric', )); $product = new Product; $product->title = $request->input('title'); $product->slug = $request->input('slug'); $product->user_id = $request->input('user_id'); $product->description = $request->input('description'); $product->short_description = $request->input('short_description'); $product->subcategory_id = $request->input('subcategory_id'); $product->discount = $request->input('discount'); $product->discount_date = $request->input('discount_date'); $product->price = $request->input('price'); if ($request->hasFile('image_one')) { $image = $request->file('image_one'); $filename = 'product' . '-' . time() . '.' . $image->getClientOriginalExtension(); $location = public_path('images/'); $request->file('image_one')->move($location, $filename); $product->image = $filename; } $product->save(); $product->attributes()->sync($request->attributes, false); //Display a successful message upon save Session::flash('flash_message', 'Product, '. $product->title.' created'); return redirect()->route('admin.products.index'); } /** * Show the form for editing the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function edit($id) { $product = Product::find($id); $categories = Category::all(); $users = User::all(); $subcategories = Subcategory::all(); $attributes = Attribute::all(); $attributes2 = array(); foreach($attributes as $attribute) { $attributes2[$attribute->id] = $attribute->title; } return view('admin.products.edit', compact('product', 'categories', 'users', 'subcategories', 'attributes2')); } /** * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param int $id * @return \Illuminate\Http\Response */ public function update(Request $request, $id) { $product = Product::find($id); if ($request->input('slug') == $product->slug) { $this->validate($request, array( 'title'=>'required|max:225', 'description' =>'required|min:4|max:100000', 'short_description' =>'nullable|min:4|max:1000', 'image_one' =>'sometimes|image', 'image_two' =>'sometimes|image', 'image_three' =>'sometimes|image', 'image_four' =>'sometimes|image', 'discount' =>'nullable|numeric', 'discount_date' =>'nullable|date', 'user_id' =>'required|numeric', 'price' =>'required|numeric', 'subcategory_id' => 'sometimes|integer', )); } else { // validate the date $this->validate($request, array( 'slug' =>'required|max:225|unique:products', 'title'=>'required|max:225', 'description' =>'required|min:4|max:100000', 'short_description' =>'nullable|min:4|max:1000', 'image_one' =>'sometimes|image', 'image_two' =>'sometimes|image', 'image_three' =>'sometimes|image', 'image_four' =>'sometimes|image', 'discount' =>'nullable|numeric', 'discount_date' =>'nullable|date', 'user_id' =>'required|numeric', 'price' =>'required|numeric', 'subcategory_id' => 'sometimes|integer', )); } $product = Product::where('id',$id)->first(); $product->title = $request->input('title'); $product->description = $request->input('description'); $product->slug = $request->input('slug'); $product->user_id = $request->input('user_id'); $product->short_description = $request->input('short_description'); $product->image_one = $request->input('image_one'); $product->image_two = $request->input('image_two'); $product->image_three = $request->input('image_three'); $product->image_four = $request->input('image_four'); $product->discount = $request->input('discount'); $product->discount_date = $request->input('discount_date'); $product->price = $request->input('price'); $product->subcategory_id = $request->input('subcategory_id'); if ($request->hasFile('image_one')) { $image = $request->file('image_one'); $filename = 'product' . '-' . time() . '.' . $image->getClientOriginalExtension(); $location = public_path('images/'); $request->file('image_one')->move($location, $filename); $oldFilename = $product->image_one; $product->image_one = $filename; Storage::delete($oldFilename); } $product->save(); $product->attributes()->sync($request->attributes); return redirect()->route('products.index', $product->id)->with('flash_message', 'Product, '. $product->title.' updated'); } /** * Remove the specified resource from storage. * * @param int $id * @return \Illuminate\Http\Response */ public function destroy($id) { $product = Product::findOrFail($id); $product->attributes()->detach(); Storage::delete($product->image); $product->delete(); return redirect()->route('products.index') ->with('flash_message', 'Product successfully deleted'); } }

Product model

根据 <?php namespace App; use Illuminate\Database\Eloquent\Model; class Product extends Model { protected $table = 'products'; protected $fillable = [ 'title', 'slug', 'image_one', 'image_two', 'image_three', 'image_four', 'short_description', 'description', 'price', 'discount', 'discount_date', ]; public function category(){ return $this->belongsTo(Category::class); } public function subcategory(){ return $this->belongsTo(Subcategory::class); } public function attributes() { return $this->belongsToMany(Attribute::class, 'product_attributes', 'product_id', 'attribute_id'); } public function order(){ return $this->hasMany(Order::class); } public function discounts(){ return $this->hasMany(Discount::class, 'product_id', 'id'); } } 回答更新3:

现在我有折扣表,一切都已设定,这是我的Bagus Tesa

discountcontroller

这是我的<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Discount; use App\Product; class DiscountController extends Controller { public function __construct() { $this->middleware(['auth', 'isAdmin']); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { $discounts = Discount::orderby('id', 'desc')->get(); $products = Product::all(); return view('admin.discounts.index', compact('discounts', 'products')); } /** * Store a newly created resource in storage. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\Response */ public function store(Request $request) { //Validating title and body field $this->validate($request, array( 'amount'=>'required|max:225', 'valid_from' =>'required|date', 'valid_to' =>'required|date', 'product_id' => 'required|numeric', )); $discount = new Discount; $discount->amount = $request->input('amount'); $discount->valid_from = $request->input('valid_from'); $discount->valid_to = $request->input('valid_to'); $discount->product_id = $request->input('product_id'); $discount->save(); } /** * Display the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function show($id) { // } /** * Show the form for editing the specified resource. * * @param int $id * @return \Illuminate\Http\Response */ public function edit($id) { // } /** * Update the specified resource in storage. * * @param \Illuminate\Http\Request $request * @param int $id * @return \Illuminate\Http\Response */ public function update(Request $request, $id) { // } /** * Remove the specified resource from storage. * * @param int $id * @return \Illuminate\Http\Response */ public function destroy($id) { // } }

discount model

更新4:

现在一切正常,除了在所有这些变化之前结束折扣时间。

issue image

正如您在屏幕截图中看到的那样,到期时间仍未到来,但折扣状态已过期。

以下是我在我的刀片中使用的代码:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Discount extends Model
{
    protected $table = 'discounts';

    protected $fillable = ['valid_from', 'valid_to', 'amount', 'product_id',];

    public function products(){
       return $this->belongsTo(Product::class, 'product_id', 'id');
   }

   public function scopeValid($query){
         return $query->whereDate('valid_from', '>=', Carbon::today()->toDateString())
                      ->whereDate('valid_to', '<=', Carbon::today()->toDateString());
   }
}

这是在我的控制器中:

@if ($product->$discounts > $mytime)
 OK!
@else
 Expired!
@endif

3 个答案:

答案 0 :(得分:4)

我建议将discountdiscount_date提取到自己的表格中,例如

discounts (
    datetime valid_from, 
    datetime valid_to, 
    int product_id, 
    decimal amount
) 

然后只查找对给定日期和产品有效的折扣,例如

SELECT product_id, amount 
FROM discounts 
WHERE product_id = 42
AND (NOW() BETWEEN valid_from AND valid_to);

虽然这需要额外的查询或联接以获取折扣,但更容易在自己的表中维持折扣。您无需删除过期折扣,因为BETWEEN查询确保您只获得当前有效的折扣。

此外,通过这种方式,您可以保留折扣的历史记录。丢弃列时你会丢失的东西。即使您想删除它们,也会更容易,因为您可以删除NOW() > valid_to的所有折扣。

不幸的是,我不知道如何用Laravel / Eloquent做到这一点。但这更多是关于数据库建模而不是关于特定框架。你的框架应该允许这个。我确信它确实以某种方式。但我不知道怎么做。

注意:我从头脑中输入了代码片段。您想要doublecheck their syntax

答案 1 :(得分:2)

原始问题

  

我正在使用Laravel 5.5从事电子商务项目,在我的产品表中我有2列名为discount和discount_date,我想要的是当discount_date列的日期同时折扣和discount_date列自动变为null时

答案:

有几种方法可以解决这个问题:

我将继续将戈登的方法扩展到Laravel的方式,因为它具有保留较旧折扣的能力。

戈登解释说有一张如下表所示的表格。

discounts (
    int id,
    datetime valid_from, 
    datetime valid_to, 
    int product_id, 
    decimal amount,
    datetime created_at,
    datetime updated_at
) 

注意:表格结构略有改变,以遵循Laravel的惯例(created_atupdated_at;为了清晰起见,还添加了主键。

要创建此类表格,您可以自行触发查询或使用Laravel's Migration。我不会介绍数据库创建,因为很不清楚您是直接使用MySQL / MariaDB还是帮助PhpMyAdmin,或者您自己也可以使用Laravel迁移。假设您已准备好表格,名为discounts,我们将不得不在Laravel中添加新模型:

<?php

namespace App;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;

class Discount extends Model
{
  protected $table = 'discounts';
  protected $dates = ['valid_from', 'valid_to'];

  public function products(){
        return $this->belongsTo(Product::class, 'product_id', 'id');
  }

  public function scopeValid($query){
        return $query->where('valid_from', '>=', Carbon::now()->toDateTimeString())
                     ->where('valid_to', '<', Carbon::now()->toDateTimeString());
  }
}

您需要添加具有以下关系的Product模型:

public function discounts(){
    return $this->hasMany(Discount::class, 'product_id', 'id');
}

请注意scopeValid($query),它是我们对有效折扣进行过滤的快捷方式 - 您可以在文档中查看Laravel Scopes->whereDate是Laravel中的特定function to query datetime field,您可以在Laravel Diary中找到一些示例。这样,您可以使用以下雄辩查询过滤Product的折扣以获得折扣:

Product::find(1)->discounts()->valid()->get();

这种方法的专家是:

  • 您可以追踪折扣历史
  • 易于维护,更少&#39;任务计划程序&#39;麻烦。
  • 可供程序员阅读。

这种方法的缺点是:

  • 如果有两个有效折扣,你可能会摔倒。但是我不认为我们可以使用datetime for primary keys ..如果它们在10月10日到10月15日跨越,另一个跨越10月11日到10月14日那么重叠怎么办?有趣的不是它。也许那里的DBA可以建议少代码麻烦的方法?每次在transaction内添加新折扣时,都可以通过检查折扣表来解决此问题。

您的下一个问题:

  

OK!更令人困惑的是:))),我把我的控制器包括在内请现在看看我有哪些字段以及我应该把代码放在哪里。欣赏它。

下一个答案:

我们不知道这个折扣将在何处使用..我认为它将显示在您的show($slug)视图(admin.products.show)中或计算总价时...类似于(?)我们是程序员(和DBA,我想),而不是魔术师..

修改 愚蠢的我忘了Carbon::today()只给你今天的日期而toDateString()只会给你一个日期部分。因此,时间参考应为Carbon::now()->toDateTimeString()

修改 查询错误,应根据日期和时间where进行过滤。

答案 2 :(得分:1)

如果您确实要将值设置为null,则可以使用MySQL Event Scheduler

但我认为将select语句修改为类似的方法更简单:

select 
    id,
    IF(discount_date > now(), discount,null) as discount,
    IF(discount_date > now(), discount_date,null) as discount_date 
from product

您可以在rextester.com

上对此进行测试

在laravel中它应该是这样的:

 $products = Product::orderby('id', 'desc')->select('all','your','columns', 'IF(discount_date > now(), discount,null) as discount', 'IF(discount_date > now(), discount_date,null) as discount_date')->get();

$countdown = DB::table('products')->where('discount_date', '>', 'now()')->pluck('discount_date');