Laravel:避免在数据库中重复条目

时间:2019-08-22 20:27:34

标签: php laravel

我正在构建Laravel API。我有一个名为Reservations的模型。我要避免用户为相同的产品和时间段创建两个预订。

我有以下内容:

$reservation =  Reservation::firstOrCreate([
   'listing_id'    =>  $request->listing_id,
   'user_id_from'  =>  $request->user_id_from,
   'start_date'    =>  $request->start_date,
   'end_date'      =>  $request->end_date,
]);
return new ReservationResource($reservation);

文档说:

  

firstOrCreate方法将尝试查找数据库记录   使用给定的列/值对

上面的代码有效:

  • 它确实将项目添加到数据库(如果尚不存在) 在这种情况下,对REST API的回复将返回新的模型实例 这是正确的。
  • 如果组合等于listing_id, user_id_from, start_date and end_date,则不会将项目添加到数据库中。

但是,在后一种情况下(该项目已经存在),它还将在REST API中返回带有匹配行ID的保留。

示例:在下表中,已经存在ID为2的预订:

id  listing_id  user_id_from    start_date  end_date
------------------------------------------------------  
1      2            3               2019-09-12  2019-10-14  

发送以下REST API请求:

{
    "listing_id": 2,
    "user_id_from": 3,
    "start_date": "2019-09-12",
    "end_date": "2019-10-14",
}

返回

"data": {
    "id": 1,
    "user_id_from": 3,
    "listing_id": 2,
    "price": 388,
    "start_date": "2019-09-12",
    "end_date": "2019-10-14",
 }

我希望收到一个JSON答复,说明该项目已经存在。如何实现?

2 个答案:

答案 0 :(得分:1)

firstOrCreate()只是您希望的两部分功能,它在first()上进行查找,如果不存在,则会退回到create()。您可以在控制器中实现几乎相同的逻辑,并将消息添加到first()结果(如果存在)中,并按原样返回结果(如果已创建)。或者,您可以根据结果用HTTP_OKHTTP_CREATED修改响应。或两者兼有。

public function store(Request $request)
{
    $attributes = [
        'listing_id' => $request->input('listing_id'), 
        'user_id_from' => $request->input('user_id_from'), 
        'start_date' => $request->input('start_date'),
        'end_date' => $request->input('end_date')
    ];

    // return existing reservation if exists
    $reservation = Reservation::where($attributes)->first();

    if ($reservation !== null) {
        // add explicit message here if you want
        return response(json_encode($reservation), Response::HTTP_OK);
    }

    // else create a new one
    $reservation = Reservation::create($attributes);

    // reload model
    $reservation = Reservation::find($reservation->id);

    return response(json_encode($reservation), Response::HTTP_CREATED);
}

答案 1 :(得分:0)

我认为您正在寻找Laravel的wasRecentlyCreated

if(! $reservation->wasRecentlyCreated){ 
      // create & encode a JSON response  or use this variable & method on the blade page
}