简体   繁体   中英

Understanding rails has_one has_many model associations

I'm trying to understand a rails model association and having trouble figuring out what association I need to use:

Here's my app Models

Company ---- Subscription ---- SubscriptionType

The SubscriptionType has a list of 3 different types of subscriptions and their associated price.

A Company has_one :subscription .

A Subscription will belong_to :company .

It also has other fields, such as trial_start_date , trial_end_date , charge_date , etc.

At first, I thought that Subscription has_one SubscriptionType and SubscriptionType has_many Subscriptions however that relationship doesn't seem to work in my subscription_spec.rb

it { should have_one(:subscription_type) }

But that gives me the following error, which indicates that this relationship won't work since I don't want to have tons of records in the SubscriptionType table:

Expected Subscription to have a has_one association called subscription_type (SubscriptionType does not have a subscription_id foreign key.)

Can someone help me wrap my head around this?

The difference between has_one vs belongs_to is all about where the foreign key lives .

Subscription has_one :subscription_type means that SubscriptionType has a subscription_id column and belongs to only one Subscription .

Subscription belongs_to :subscription_type means that Subscription has a subscription_type_id column and SubscriptionType can belong to multiple Subscription s.

So to answer your question, the correct relationship here is

class Subscription < ApplicationRecord
  belongs_to :subscription_type
end

class SubscriptionType < ApplicationRecord
  has_many :subscriptions
end

You can set the associations like this:

class Company < ApplicationRecord
  has_one :subscription
end

# subscriptions table should have columns company_id and subscription_type_id 
class Subscription < ApplicationRecord
  belongs_to :company
  belongs_to :subscription_type
end

class SubscriptionType < ApplicationRecord
  has_many :subscriptions
end

With this setup, the associated objects can be accessed as:

company = Company.find(1)
# to get subscription object with company_id: 1
company.subscription 
# to get subscription_type object of the company's associated subscription
company.subscription.subscription_type 
# to get all subscriptions of a particular subscription_type
SubscriptionType.last.subscriptions

Then, your subscription_spec.rb looks like:

it { should belong_to(:company) }
it { should belong_to(:subscription_type) }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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