Search code examples
ruby-on-railsruby-on-rails-4rails-models

Specify an optional reference in your Rails model


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.


Solution

  • 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.