Question

I have a Sponsors model and a Promo Codes model.

  • A sponsor can have zero or more promo codes
  • A promo code can have zero or one sponsors

Thus a promo code should have an optional reference to a sponsor, that is, a sponsor_id that may or may not have a value. I'm not sure how to set this up in Rails.

Here's what I have so far:

# app/models/sponsor.rb
class Sponsor < ActiveRecord::Base
  has_many :promo_codes  # Zero or more.
end

# app/models/promo_code.rb
class PromoCode < ActiveRecord::Base
  has_one :sponsor  # Zero or one.
end

# db/migrate/xxxxx_add_sponsor_reference_to_promo_codes.rb
# rails g migration AddSponsorReferenceToPromoCodes sponsor:references
# Running migration adds a sponsor_id field to promo_codes table.
class AddSponsorReferenceToPromoCodes < ActiveRecord::Migration
  def change
    add_reference :promo_codes, :sponsor, index: true
  end
end

Does this make sense? I'm under the impression that I have to use belongs_to in my Promo Codes model, but I have no basis for this, just that I've haven't seen a has_many with has_one example yet.

Was it helpful?

Solution 2

This looks like a simple has_many and belongs_to relationship:

# app/models/sponsor.rb
class Sponsor < ActiveRecord::Base
  has_many :promo_codes  # Zero or more.
end

# app/models/promo_code.rb
#table has sponsor_id field
class PromoCode < ActiveRecord::Base
  belongs_to :sponsor  # Zero or one.
end

has_one isn't appropriate here, as it would replace has_many: ie, you either have "has_many" and "belongs_to" OR "has_one" and "belongs_to". has_one isn't generally used much: usually it is used when you already have a has_many relationship that you want to change to has_one, and don't want to restructure the existing tables.

OTHER TIPS

In Rails 5, belongs_to is defined as required by default. To make it optional use the 'optional' option :)

class User
  belongs_to :company, optional: true
end

Source: https://github.com/rails/rails/issues/18233

Unless you specify validation, relationships are optional by default.

The belongs_to is to tell rails the other half of the relationship between those two objects so you can also call @promo_code.sponsor and, vice versa, @sponsor.promo_codes.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top