Ruby on Rails基于自定义字符串列建立模型一对多关联的报错解决
解决Ruby on Rails中基于Stripe客户ID的一对多模型关联问题
问题根源
你遇到的ActiveRecord::RecordInvalid: Validation failed: Customer must exist错误,是因为Rails默认会用模型的主键(id字段)匹配关联,但你需要用stripe_customer_id(Customer模型中是stripe_costumer_id)作为关联键,之前的配置缺少了指定Customer模型的关联主键,导致Rails无法正确匹配对应记录。
正确的模型关联配置
首先注意字段拼写:你的Customer模型字段是stripe_costumer_id(拼写为costumer),Subscription是stripe_customer_id,如果是笔误建议统一修正为stripe_customer_id,避免后续混淆。以下配置基于你当前的字段结构:
Customer模型
class Customer < ApplicationRecord has_many :subscriptions, class_name: 'Subscription', foreign_key: :stripe_customer_id, primary_key: :stripe_costumer_id end
Subscription模型
class Subscription < ApplicationRecord belongs_to :customer, class_name: 'Customer', foreign_key: :stripe_customer_id, primary_key: :stripe_costumer_id, optional: false # 保留存在验证,若不需要可改为true end
关键配置说明
primary_key: :stripe_costumer_id:告诉Rails使用Customer模型的stripe_costumer_id作为关联匹配的主键,而非默认的id字段foreign_key: :stripe_customer_id:指定Subscription模型中用于关联的外键字段- 关联名称统一为
customer和subscriptions更符合Rails约定,你之前使用的paywall_customer等别名也可保留,但需保证两边配置一致
创建订阅的正确方式
确保创建订阅时,stripe_customer_id的值与对应Customer记录的stripe_costumer_id一致,或通过关联对象赋值:
# 方式1:通过Customer对象创建 customer = Customer.find_by(stripe_costumer_id: 'stripe_xxxx') customer.subscriptions.create(其他字段: 对应值) # 方式2:直接指定关联字段与对象 Subscription.create(stripe_customer_id: 'stripe_xxxx', customer: customer)
额外建议
如果stripe_costumer_id是拼写错误(应为stripe_customer_id),请优先修改数据库字段名和模型属性,保持字段名一致,减少后续维护隐患。
内容的提问来源于stack exchange,提问作者john bowlee
相关产品推荐
相关产品推荐

