ruby-on-railsrspecfactory-botsingle-table-inheritance

Single Table Inheritance with Factory Girl in Rails


I'm making a Rails 4.0.1 app using Capybara and FactoryGirl but I'm having trouble getting my tests to work correctly.

I'm using single table inheritance to make a Collection < ActiveRecord::Base and a VideoCollection < Collection model. When using Factory Girl in my tests, the models don't seem to get instantiated as they should.

The Details:

The Code:

My Model(s):

# ------in app/models/collection.rb------
class Collection < ActiveRecord::Base
end

# ------in app/models/video_collection.rb------
class VideoCollection < Collection
end

# ------in db/schema.rb------ 
create_table "collections", force: true do |t|
  t.string   "type"
  t.datetime "created_at"
  t.datetime "updated_at"
  t.string   "name"
  t.string   "tile_image_link"
end

My Factory:

FactoryGirl.define do
...
  factory :collection do |collection|

    factory :video_collection, class: VideoCollection, parent: :collection do |u|
      u.sequence(:name) { |n| "Video Collection #{n}" }
      tile_image_link   "some-link.png"
      type "VideoCollection"
    end
  end
...
end

My test:

# -----in spec/requests/video_collections_spec.rb-----
require 'spec_helper'
describe "VideoCollections" do

  let(:video_collection) do 
    FactoryGirl.create(:video_collection) 
  end

  ...

  ###  This test fails ###
  expect(page).to have_link(video_collection.name, 
                            href: "video/#{video_collection.id}") 

The test output:

Failure/Error: expect(page).to have_link(video_collection.name,
   expected #has_link?("Video Collection 1", {:href=>"video/181"}) to return true, got false

I don't understand why the video_collection records from the factory aren't getting inserted properly when the test runs. It's even more baffling to me that fact that I can insert them from the console with the same command with no problem. Is there an error in my factory code somewhere?

Thanks for the help!


Solution

  • Change:

    let(:video_collection) do 
      FactoryGirl.create(:video_collection) 
    end
    

    to:

    let!(:video_collection) do 
      FactoryGirl.create(:video_collection) 
    end
    

    The difference between the two is the ! (exclamation point) after the let