2017-07-07 132 views
0

(事先说一句抱歉的长期职位)能言善辩“whereDate” Laravel 5.4升级后不能正常工作

我从laravel 5.2升级我的应用程序,以5.4的过程,因为这一直停留在这个问题上早上。出于某种原因,我的查询选择即将到来的商业事件与Eloquent'whereDate'没有返回任何东西,即使其他所有事情都指向它应该工作的事实!

我有一个phpUnit测试,不会通过尝试和本地化的问题。 (见下文)

我有一个 '业务' 模式:

<?php 

namespace App; 

use Illuminate\Database\Eloquent\Model; 

class Business extends Model 
{ 
    protected $table = 'businesses'; 
    .. 

public function businessEvents(){ 
    return $this->hasMany('App\BusinessEvent', 'business_id'); 
} 

除了作为一个 'BusinessEvent' 模式:

<?php 

namespace App; 

use Illuminate\Database\Eloquent\Model; 

class BusinessEvent extends Model 
{ 
    protected $table = 'business_events'; 
    protected $fillable = ['business_id', ..., 'start_date', 'end_date']; 

    public function business(){ 
     return $this->belongsTo('App\Business', 'business_id'); 
    } 
... 

这两者我做哑在我的测试版本。伪“业务”适用于其他测试,但我介绍了这个测试用例下面假人business_event'

protected function createMockBusinessEventWithUpcomingDateTime($businessId){ 
    $faker = Faker::create(); 

    $businessEvent = BusinessEvent::create([ 
     'business_id' => $businessId, 
     'name'   => $faker->name, 
     'description' => $faker->text, 
     'start_date' => date("Y-m-d H:i:s", strtotime(date("Y-m-d H:i:s")."+30 minutes")), 
     'end_date'  => date("Y-m-d H:i:s", strtotime(date("Y-m-d H:i:s")."+1 hour +30 minutes")) 
    ]); 

    ... 

    $business = Business::find($businessId); 
    if($business){ 
    $businessEvent->business()->associate($business); 
    } 

    return $businessEvent; 
} 

现在,这里是真正的测试功能:

public function testGetUpcomingN(){ 

    $this->businessEvent = $this->createMockBusinessEventWithUpcomingDateTime($this->business->id); 

    $response = $this->json('GET', '/api/v1/business/'.$this->business->id.'/events/upcoming/2'); 

    $this->outp($response->content()); 

    $this->outp("Testing Assertions"); 
    $this->assertEquals(200, $response->status()); 
    $this->assertEquals($this->business->businessEvents()->first()->id, $this->businessEvent->id);  
} 

测试不会失败,这意味着该事件正确地与业务关联,并且无论我如何查询api端点(HttpRequester,记录结果,测试中的返回值,生产...),它总是返回一个空的阵!

以下功能就是所谓的控制器(也验证了!):

public function upcomingN($businessId, $n){ 
    Log::info('Get upcoming '.$n.' recorded events for business with id: '.$businessId); 
    $business = Business::find($businessId); 
    if (is_null($business)){ 
     Log::warning('No business exists with given id. Exiting.'); 
     return response('No Content.', 204); 
    } 

    $currentDate = date('Y-m-d H:i:s'); 

    $greaterThan = $business->businessEvents()->first()->end_date >= $currentDate; 
    Log::info("Greater THAN:", [$greaterThan]); 

    $events = $business->businessEvents()->whereDate('end_date', '>=', $currentDate)->take($n)->get(); 

    if (!is_null($events)){ 
     Log::info('Got upcoming N recorded events for business with id: '.$businessId, (array) $events); 
     return response()->json($events); 
    } 

    return response('No Content.', 204); 
} 

正如你所看到的,我甚至尝试登录了“$大于”布尔值,应该测试完全相同的“whereDate”所做的事情,它的计算结果为true!我已经尝试了Carbon :: parse() - ing,设置语言环境,现在我几乎没有想法。

老功能,在5.2的工作:

public function upcomingN($businessId, $n){ 
    Log::info('Get upcoming N recorded events for business with id: '.$businessId); 
$business = Business::find($businessId); 
if (is_null($business)){ 
    Log::warning('No business exists with given id. Exiting.'); 
     return response('No Content.', 204); 
    } 

    $currentDate = date('Y-m-d H:i:s'); 
    $events = $business->businessEvents()->whereDate('start_date', '>=', $currentDate)->take($n)->get(); 

    if (!is_null($events)){ 
     Log::info('Got upcoming N recorded events for business with id: '.$businessId, (array) $events); 
     return response()->json($events); 
    } 

    return response('No Content.', 204); 
} 

有一件事我也有在升级过程中的变化是使用mysql-DB设置为不严格,因为Laravel在抱怨缺乏默认值。但是,我检查了数据库并且测试条目正确填充。

任何帮助将不胜感激!

+0

我觉得你应该先登录'$米的商务> businessEvents的值() - > first() - > end_date',看看它返回什么,然后你可以告诉它可以告诉你是否有更多的考虑 –

+0

我做了日志的值,它是'“2017-07-07 18:32:01 “',而比较值(当前日期)输出为”“2017-07-07 17:29:39”'。正是我所期望的:/ – bnunamak

+1

在我的脑海里有两件事可以检查:我对字符串或日期时间对象的日期时间比较没有那么自信,因为根据内部转换,Laravel的模型日期时间字段可能是作为一个字符串或碳对象返回,所以我可能会建议,即使你可以简单地使用:Carbon :: now() - > greaterThan(Carbon :: parse($ business-> businessEvents() - > first() - > end_date));'也尽量不要使用'whereDate()'并使用'where()' –

回答

2

感谢这么多Omisakin Oluwatobi,该解决方案是用雄辩的事实“其中”而不是“whereDate”,为“whereDate”只比较日期,而不是日期时间(事后看来这在明显)。

如果您可以使用相同数量的代码实现与'where'相同的结果,我觉得'whereDate'函数存在有点令人困惑。

我可以验证(单元测试),下面的最终解决方案适用于未来的选择和日期时间过去忽略的:

public function upcomingN($businessId, $n){ 
    Log::info('Get upcoming '.$n.' recorded events for business with id: '.$businessId); 
    $business = Business::find($businessId); 

    if (is_null($business)){ 
     Log::warning('No business exists with given id. Exiting.'); 
     return response('No Content.', 204); 
    } 

    $currentDate = date('Y-m-d H:i:s'); 
    $events = $business->businessEvents()->where('end_date', '>=', $currentDate)->take($n)->get(); 

    if (!is_null($events)){ 
     Log::info('Got upcoming N recorded events for business with id: '.$businessId, (array) $events); 
     return response()->json($events); 
    } 

    return response('No Content.', 204); 
}