Laravel 5 firstOrCreate 保持创建甚至设置唯一的字段
Posted
技术标签:
【中文标题】Laravel 5 firstOrCreate 保持创建甚至设置唯一的字段【英文标题】:Laravel 5 firstOrCreate keep create even set unique to the field 【发布时间】:2015-08-09 04:05:04 【问题描述】:下面是我的应用\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'];
下面是我的应用\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]);
如果会话密钥存在于表 cart.sess 中,我想要检查数据库,否则创建新的并获取 id。
问题是,当它不断为数据库创建新的重复会话时。
我可以知道我哪里做错了吗?
谢谢
更新 [2015-05-27 16:02]: 在我 TRUNCATE 表并将 sess 字段设置为 Unique 后,第一次提交它看起来没问题,当第二次提交时显示以下错误:
更新 [2015-05-27 16:16] 我用来创建数据库的代码:
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;
【问题讨论】:
因为它是你自己的会话 ID,除非你的会话发生变化,否则它不会改变 @user1578359 你可以执行以下 Cart::whereSess($sessId)->whereStatus(1)->firstOrCreate() 并告诉我们这是否有效。 +shaddy 在这里放了一个 arg,让你的 'sess' 列也独一无二。 【参考方案1】:我解决了这个问题。 在哪里 因为在我的模态中我使用了 SoftDeletes; 如何解决 它不能在此字段内具有默认值, 但是我将其设置为 Default 0000-00-00 00:00:00 ,默认情况下将其设置为 null 。
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;
到
deleted_at
时间戳
为什么 firstOrCreate 做了这个查询(检查下面的图片)
上面的插件是:https://github.com/barryvdh/laravel-debugbar谁需要它。
谢谢
【讨论】:
【参考方案2】:在您创建此购物车表的数据库架构中,sess
列应该是唯一的,但事实并非如此。你应该改变它,让它变得独一无二:
$table->unique('sess');
在此之前不要忘记删除所有记录,否则会出错。
编辑在您发布表架构后,我发现了问题
sess varchar(40) NOT NULL
您必须将sess
的长度设置为至少 255 个字符或会话 ID 的大小,因为您的会话 ID 超过 40 个符号。 Laravel 尝试查找包含 64 个字符(或会话 id 长度)的字符串,例如:
8a9f119eaea027def7268d12e4e4d680
但没有,所以它会尝试插入新的。由于您的列长度为 40,因此 sess id 被截断为 40 个符号:
8a9f119eaea
在下一次检查中它不会匹配,因为它正在搜索8a9f119eaea027def7268d12e4e4d680
,但在您的数据库中您得到了8a9f119eaea
。
【讨论】:
您好,感谢您的回答,但是当我将字段更改为唯一时,它会显示重复错误。我更新了我的问题。 @user1578359 您能否在问题中发布您创建此表的代码(数据库模式),以便我可以尝试重现您的问题? 嗨,@shaddy 我使用 mysql 代码手动创建数据库。更新为问题。 我找到了问题,请看我编辑的答案:) 嗨@shaddy,在我截断并将varchar更改为255并尝试更改为文本后,问题仍然存在重复错误。还是我的 firstOrCreate() 函数有什么问题?以上是关于Laravel 5 firstOrCreate 保持创建甚至设置唯一的字段的主要内容,如果未能解决你的问题,请参考以下文章
在 Laravel 中,有没有办法找出是不是创建了 `firstOrCreate` 或者是不是找到了行?
Laravel 8 - firstOrCreate() 不返回数据库中设置的默认值
laravel中firstorcreate和updateorcreate的操作区分