Cashier创建Stripe订阅时数据库未写入完整数据求助
排查Laravel Cashier订阅数据写入不全问题
我来帮你梳理这个棘手的问题,看起来你已经做了不少基础排查,咱们一步步来定位根源:
问题背景
昨天用Laravel Cashier创建订阅功能完全正常,今天突然异常:Stripe端已经成功生成订阅并返回了完整数据,但应用的subscriptions表只写入了user_id、updated_at、created_at、id这4个基础字段,你传入的name、stripe_id、stripe_plan等核心字段都没有被写入。
你已经做的排查:
- 注释的
dd()输出确认所有传入的字段数据都是完整有效的 - 之前用户注册时遇到过类似问题,添加构造函数
public function __construct(array $attributes = []) { parent::__construct($attributes); }解决了,但添加后订阅功能失效 - 尝试移除该构造函数、给
subscriptions模型添加该构造函数,均无效果 - 已经配置了模型的
fillable数组,且此前功能正常
可能的解决方案与排查方向
1. 再次确认Subscription模型的$fillable配置
虽然你说已经配置了fillable,但还是要仔细核对是否包含了所有需要写入的字段,避免拼写错误或遗漏:
class Subscription extends Model { protected $fillable = [ 'name', 'stripe_id', 'stripe_plan', 'quantity', 'trial_ends_at', 'ends_at', 'user_id' ]; }
如果之前不小心修改了这个数组,或者字段名写错(比如把stripe_plan写成stripe_plan_id),都会导致批量赋值失败。
2. 检查是否有模型观察者/全局事件干扰
如果项目中存在全局模型创建事件,或者Subscription模型自己的观察者,可能会在创建过程中修改或拦截字段写入。可以临时禁用事件调度器测试:
// 在create()之前临时禁用事件 Subscription::unsetEventDispatcher(); $this->owner->subscriptions()->create([ 'name' => $this->name, 'stripe_id' => $subscription->id, 'stripe_plan' => $this->plan, 'quantity' => $this->quantity, 'trial_ends_at' => $trialEndsAt, 'ends_at' => null, ]);
如果这样能正常写入所有字段,那就要去排查对应的观察者逻辑,看是否有错误拦截了字段。
3. 重点排查构造函数的影响
你提到添加构造函数后出现问题,Cashier的Billable trait本身已经处理了模型的初始化逻辑,手动添加构造函数可能会干扰它的默认行为:
- 建议移除
User和Subscription模型中所有自定义的构造函数,除非你完全清楚Cashier的底层逻辑,并且在构造函数中正确调用父类方法且未修改$fillable、$guarded等核心属性 - 之前解决用户注册问题的构造函数,可以尝试用其他方式替代:比如检查用户模型的
$fillable是否正确,或者临时设置$guarded = [](仅测试用,不推荐生产环境)
4. 验证数据库表结构
确认subscriptions表的字段是否存在、类型是否正确:
name、stripe_id、stripe_plan应为字符串类型(如varchar(255))quantity应为整数类型trial_ends_at、ends_at应为datetime/timestamp类型且允许为空
如果不小心修改了表结构(比如删除了某个字段、设置了错误的非空约束),也会导致字段无法写入。
5. 查看实际执行的SQL语句
开启查询日志,看看框架实际执行的INSERT语句包含哪些字段:
DB::enableQueryLog(); $this->owner->subscriptions()->create([ // 你的字段参数 ]); dd(DB::getQueryLog());
如果SQL语句里没有你传入的字段,说明问题出在模型层的批量赋值;如果有字段但未写入,那大概率是数据库层面的问题(如字段不存在、默认值覆盖等)。
内容的提问来源于stack exchange,提问作者Tallal
相关产品推荐
相关产品推荐

