LearningRoR
LearningRoR

Reputation: 27242

Rspec: Why isn't my model valid in general?

The issue has to do with my factories but I'll show my location_spec.rb first:

require 'spec_helper'

describe Location do

  before(:each) do
    @location = FactoryGirl.build(:location)
  end

  subject { @location }

  describe "should be valid in general" do
    it { should be_valid }
  end

  describe "when user_id is not present" do
    before { @location.user_id = nil }
    it { should_not be_valid }
  end

  describe "when owner_id is not present" do
    before { @location.owner_id = nil }
    it { should_not be_valid }
  end
end

Here is my factories.rb

FactoryGirl.define do
  factory :user do
    username   'user1'
    email      '[email protected]'
    timezone   'Eastern Time (US & Canada)'
    password   'testing'
  end

  factory :owner do
    name    'Owner One'
    user
  end

  factory :location do
    name 'Location One'
    about 'About this location'
    website 'http://www.locationone.com/'
    phone_number '12 323-4234'
    street_address 'Shibuya, Tokyo, Japan'


    association :owner, strategy: :build
  end
end

Location.rb

class Location < ActiveRecord::Base
  attr_accessible :about, :name, :owner_id, :phone_number,:street_address, :website
  belongs_to :owner
  belongs_to :user
  validates_presence_of :owner_id
  validates_presence_of :user_id
end

Here is the error I get:

Failures:

  1) Location should be valid in general
     Failure/Error: it { should be_valid }
       expected valid? to return true, got false
    #./spec/models/location_spec.rb:53:in `block (3 levels) in <top (required)>'

I get this error because I'm building the associations incorrectly for Location I believe. The associations should be the user and owner are already saved and than just have the location already assigned to both. Am I on the right track with my factories or is it something else? What do you think?

Thank you in advance.

Upvotes: 0

Views: 118

Answers (1)

Chris Salzberg
Chris Salzberg

Reputation: 27374

The strategy: :build option is telling FactoryGirl not to actually save the associated model (owner) for both FactoryGirl.create and FactoryGirl.build. I don't think this is what you want.

Try changing the factory line with the owner to just owner, like this:

factory :location do
  name 'Location One'
  about 'About this location'
  website 'http://www.locationone.com/'
  phone_number '12 323-4234'
  street_address 'Shibuya, Tokyo, Japan'

  owner
end

What that will do is to create the association before instantiating the location record, so that the location will be valid. If you don't do this, then validation on the parent (location) will fail because there will be no owner_id to assign (the owner will not have been created yet).

UPDATE:

It looks like you're also missing the user association in your location factory, which it also validates. So add that to your factory as well to get it to pass:

factory :location do
  name 'Location One'
  about 'About this location'
  website 'http://www.locationone.com/'
  phone_number '12 323-4234'
  street_address 'Shibuya, Tokyo, Japan'

  owner
  user
end

I think that should do it.

Upvotes: 3

Related Questions