Cashier创建Stripe订阅时数据库未写入完整数据求助
兄弟,我之前用Cashier的时候也踩过类似的坑,结合你说的情况——Stripe那边订阅创建成功,但本地subscriptions表只写入了基础字段,其他字段没存进去,咱们一步步来排查:
先死磕fillable/guarded配置
虽然你说已经设置了fillable,但有时候手滑写错字段名或者不小心覆盖了配置是常有的事。打开你的Subscription模型,确保$fillable数组包含所有要写入的字段:protected $fillable = [ 'name', 'stripe_id', 'stripe_plan', 'quantity', 'trial_ends_at', 'ends_at', ];要是怕漏写,也可以临时用
protected $guarded = [];(注意这是允许所有字段批量赋值,生产环境不建议长期用)来测试,看看能不能写入。检查Subscription模型的继承关系
如果你是自定义的Subscription模型,一定要确保它正确继承了Cashier的基础模型:use Laravel\Cashier\Subscription as CashierSubscription; class Subscription extends CashierSubscription { // 你的自定义代码 }要是没继承对,Cashier内部的逻辑可能会干扰字段填充,导致你传的参数被忽略。
排查全局观察者/中间件的干扰
有没有给模型加全局的creating/saving观察者?或者有没有中间件在偷偷修改模型数据?比如有些全局观察者会强制过滤字段,这时候可以临时注释掉观察者代码,再测试一次create操作,看看字段能不能正常写入。验证字段的数据类型
重点看trial_ends_at这个字段,它需要是Carbon实例或者null,要是你传的是字符串格式的日期,可能会因为类型不匹配写不进去。可以把代码改成:'trial_ends_at' => $trialEndsAt ? Carbon::parse($trialEndsAt) : null,确保类型符合数据库的datetime字段要求。
绕过关联关系直接测试模型写入
你现在用的是$this->owner->subscriptions()->create(),试试直接用Subscription模型的create方法:Subscription::create([ 'user_id' => $this->owner->id, 'name' => $this->name, 'stripe_id' => $subscription->id, 'stripe_plan' => $this->plan, 'quantity' => $this->quantity, 'trial_ends_at' => $trialEndsAt, 'ends_at' => null, ]);如果这样能写入,说明是你的关联关系
subscriptions()里加了额外的查询约束(比如默认select了固定字段),导致批量赋值被限制。清除Laravel缓存
有时候模型的fillable配置会被缓存,试试执行这两个命令:php artisan config:clear php artisan cache:clear清完缓存再测试,说不定就正常了。
另外,你之前用户表的问题靠加构造函数解决,但Subscription模型如果继承了Cashier的模型,构造函数一定要调用父类的构造方法,而且不要在里面加任何干扰批量赋值的逻辑,比如不要在构造函数里手动设置字段值,不然可能会覆盖你传入的参数。
内容的提问来源于stack exchange,提问作者Tallal

