Kenny Ong
Kenny Ong

Reputation: 401

Laravel 5 firstOrCreate keep create even set unique to the field

Below is my app\Cart.php

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Cart extends Model {
    use SoftDeletes;
    protected $table = 'cart';
    protected $fillable = ['sess','uid'];
}

Below is my app\Http\Controllers\CartController.php

public function cart($id=0, $act, Request $request)
    {
        $sessId = Session::getId();
        switch($act){
            case 'Add':
                $quantity = $request->only('p_quantity');
                $data = $request->except('p_quantity');
                $cartId =  Cart::firstOrCreate(['sess' => $sessId,'status' => 1]);
            break;

            case 'Delete':

            break;
        }

        return response()->json(['success' => true,'message' => 'Success', 'act' => $act, 'id' => $id ,'data' => $data, 'quantity'=> $quantity, 'cart'=>$cartId->id]);
    }

What i want is check database if the session key exist in table cart.sess, else create new one and get the id.

Question is , when it keep create new duplicate session to database.

Cart Table

may i know where i did wrong?

Thanks

UPDATE [2015-05-27 16:02]: After i TRUNCATE table and set the sess field to Unique , first submit it look ok, when second submit it show error below: After change to unique

UPDATE [2015-05-27 16:16] Code that i use to create database:

CREATE TABLE IF NOT EXISTS `cart` (
  `id` int(11) NOT NULL,
  `uid` int(11) DEFAULT NULL,
  `sess` varchar(40) NOT NULL,
  `status` int(11) DEFAULT '1',
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `deleted_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

Upvotes: 4

Views: 1561

Answers (2)

Kenny Ong
Kenny Ong

Reputation: 401

I Solved the problem. Where Because in my modal i using SoftDeletes; How To Solved it cant has default value inside this field, but i set it to Default 0000-00-00 00:00:00 , just put it as null by default.

CREATE TABLE IF NOT EXISTS `cart` (
  `id` int(11) NOT NULL,
  `uid` int(11) DEFAULT NULL,
  `sess` varchar(40) NOT NULL,
  `status` int(11) DEFAULT '1',
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',

deleted_at timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'

) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

to

deleted_at timestamp

Why firstOrCreate did this query (Check Image Below) enter image description here

Plugin Above is : https://github.com/barryvdh/laravel-debugbar for who need it.

Thanks

Upvotes: 0

Sh1d0w
Sh1d0w

Reputation: 9520

In your database schema, where you created this cart table, the sess column should be unique, but it is not. You should alter it, to be unique:

$table->unique('sess');

Don't forget to delete all records before that, otherwise you will get an error.

EDIT After you posted your table schema I found the problem

sess varchar(40) NOT NULL

You must set the length of sess to at elast 255 characters or the size of your session id, because your session id is longer than 40 symbols. Laravel tries to find a string with 64 characters (or with the length of your session id) for example:

8a9f119eaea027def7268d12e4e4d680

but did not, so it tries to insert new one. Since your column is with length 40, the sess id got truncated to 40 symbols:

8a9f119eaea

and in the next check it would not match, because it is searching for 8a9f119eaea027def7268d12e4e4d680 but in your database you got 8a9f119eaea.

Upvotes: 1

Related Questions