[英]How to make Ruby on Rails model relation with custom string column
I have Customer and Subscription models in my Ruby on Rails app.我的 Ruby on Rails 应用程序中有客户和订阅模型。
Customer
id: ID
stripe_costumer_id: String
Subscription
id: ID
stripe_customer_id: String
I want to make a relation one to many between there two tables but use stripe_customer_id as foreign key.我想在两个表之间建立一对多关系,但使用 stripe_customer_id 作为外键。
I tried so far:到目前为止我试过:
Subscription
belongs_to :paywall_customer, class_name: 'Customer', foreign_key: :stripe_customer_id
Customer
has_one :paywall_subscription, class_name: 'Subscription', foreign_key: :stripe_customer_id
The problem is then when I try to create a new subscription I get this error:问题是当我尝试创建新订阅时出现此错误:
ActiveRecord::RecordInvalid: Validation failed: Customer must exist
I would be grateful if you could help me achieve to make posibile to get the relation between these two tables using stripe_costumer_id that is also a string in this case.如果您能帮助我使用 stripe_costumer_id 实现这两个表之间的关系,我将不胜感激,在这种情况下,它也是一个字符串。
You are conflating data (stripe_customer_id) with relational references (id).您将数据 (stripe_customer_id) 与关系引用 (id) 混为一谈。 It is not advisable to fight the Rails paradigm, the id field should be the foreign key.
不宜拼Rails范式,id字段应该是外键。 The stripe_customer_id field is a value that pertains to a customer, so it should just be a field in the customers table and not in the subscriptions table.
stripe_customer_id 字段是一个与客户相关的值,因此它应该只是客户表中的一个字段,而不是订阅表中的一个字段。
For one-to-many it should be:对于一对多,它应该是:
# in app/models/customer.rb
class Customer < ApplicationRecord
has_many :subscriptions
end
# in app/models/subscription.rb
# it has a column 'customer_id'
class Subscription < ApplicationRecord
belongs_to :customer
end
If you try to configure the relationship in non-Rails ways, you are bound to end up with problems.如果您尝试以非 Rails 方式配置关系,您一定会遇到问题。 Rails is opinionated, and we are obligated to conform to its opinions.
Rails 是固执己见的,我们有义务遵从它的意见。 But it's a small price to pay b/c it works so well.
但这是一个很小的代价,因为它运作良好。
UPDATE更新
You need to add primary_key: :stripe_customer_id
to the associations.您需要将
primary_key: :stripe_customer_id
添加到关联中。
And since you want a one-to-many relationship: Customer has_many:paywall_subscriptions
并且由于您想要一对多关系: Customer
has_many:paywall_subscriptions
Customer
has_many :paywall_subscriptions, class_name: 'Subscription', foreign_key: :stripe_customer_id, primary_key: :stripe_customer_id
Subscription
belongs_to :paywall_customer, class_name: 'Customer', foreign_key: :stripe_customer_id, primary_key: :stripe_customer_id
To create a Subscription, you must have stripe_customer_id
field filled in. And a Customer with that stripe_customer_id
must already exist.要创建订阅,您必须填写
stripe_customer_id
字段。并且具有该stripe_customer_id
的客户必须已经存在。
ORGINAL原创
This can work if you add the model StripeCustomer
;如果您添加 model
StripeCustomer
,这可以工作; we store the stripe_customer_id
string inside the uid
field.我们将
stripe_customer_id
字符串存储在uid
字段中。
Customer
id: ID
stripe_customer_id: String
Subscription
id: ID
stripe_customer_id: String
StripeCustomer
id: ID
uid: String
Customer
belongs_to :stripe_customer, primary_key: :uid
has_many :subscriptions, through: :stripe_customer
Subscription
belongs_to :stripe_customer, primary_key: :uid
has_one :customer, through: :stripe_customer
StripeCustomer
has_one :customer, primary_key: :uid
has_many :subscriptions, primary_key: :uid
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.