Driving out belongs_to relationship

I’d like to find a good way to drive out a belongs_to (or has_many, …) relationship. I know how to write the basic code, but I’m not comfortable with the rspec code I came up with… suggestions for improvement?

Spec

require 'spec_helper'

describe FeaturedCompany do

  it "requires a company" do
    f_company = FeaturedCompany.create  article_id: 1
    expect(f_company).to have(1).error_on(:company)
  end

  it "requires an article" do
    f_company = FeaturedCompany.create company_id: 1
    expect(f_company).to have(1).error_on(:article)
  end

  it "has one related company" do
    f_company = FeaturedCompany.create
    expect(f_company.company).to be_nil
    f_company.company = Company.new
    expect(f_company).to have(:no).errors_on(:company)
  end

  it "has one related article" do
    f_company = FeaturedCompany.create
    expect(f_company.article).to be_nil
    f_company.article = Article.new
    expect(f_company).to have(:no).errors_on(:article)
  end
end

Model

# == Schema Information
#     

    # Table name: featured_companies
    # 
    #  id         :integer          not null, primary key
    #  company_id :integer
    #  article_id :integer
    #   
        
    class FeaturedCompany < ActiveRecord::Base
      attr_accessible :company_id, :article_id
        
      belongs_to :company
      belongs_to :article
      
      validates_presence_of :company, :article
      
    end

This is after a bit of refactoring… when I first wrote the specs/validations, I started out focusing on company_id and article_id since I was clear about what I wanted there; eventually I refactored out most of the _id into to the sate you see it now. Even though that worked and eventually got me here, I’m not happy with how I did it.

Have you taken a look at the Shoulda Matchers gem? It allows you to do the following:

require 'spec_helper'

describe FeaturedCompany do
  # associations
  it { should belong_to(:company) }
  it { should belong_to(:article) }

 # validations
  it { should validate_presence_of(:company_id) }
end

Thanks very much, @joelq… that did the trick! FYI, following ThoughtBot’s coding guidelines, I actually wrote this as:

describe FeaturedCompany do
  it("belongs to a company") do
    expect(FeaturedCompany.create).to belong_to :company
  end
  ## same for :article and validations
end

following ThoughtBot’s coding guidelines, I actually wrote this as:

We should probably clarify that. The single line, implicit subject “should” that @joelq showed is not the same as foo.bar.should eq 5. The latter requires that rspec add should and should_not as monkey patches to Object, which is among the reasons that syntax has fallen out of favor.

This is a frequent point of confusion - so much so that RSpec 3 is going to add is_expected for use in those one-liners: it { is_expected.to validate_presence_of(:company_id) }