简体   繁体   English

如何使 Ruby on Rails model 与自定义字符串列建立关系

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM