po.studio
po.studio

Reputation: 4127

rspec validation failed: 'can't be blank'

I'm unable to resolve the following rspec validation error:

Failures:

  1) User treating associations should have the right treatings in the right order
     Failure/Error: FactoryGirl.create(:treating, requestor: @user, created_at: 1.day.ago)
     ActiveRecord::RecordInvalid:
       Validation failed: Requestee can't be blank
     # ./spec/models/user_spec.rb:143:in `block (3 levels) in <top (required)>'

I'm dealing with two models, User and Treating (think of it as a meeting):

user.rb

class User < ActiveRecord::Base
    attr_accessible :name, :email, :password, :password_confirmation
    has_secure_password

    has_many :sent_treatings, :foreign_key => "requestor_id", :class_name => "Treating", dependent: :destroy
    has_many :received_treatings, :foreign_key => "requestee_id", :class_name => "Treating", dependent: :destroy

end

treating.rb

class Treating < ActiveRecord::Base
  attr_accessible :intro, :proposed_date, :proposed_location

  validates :intro, presence: true, length: { maximum: 190 }
  validates :requestor_id, presence: true
  validates :requestee_id, presence: true

    belongs_to :requestor, class_name: "User"
    belongs_to :requestee, class_name: "User"

    default_scope order: 'treatings.created_at DESC'

end

Finally, the portion from my user_spec that is giving me this error:

describe "treating associations" do
        before { @user.save }
        let!(:older_treating) do
            FactoryGirl.create(:treating, requestor: @user, created_at: 1.day.ago)
            FactoryGirl.create(:treating, requestee: @user, created_at: 1.day.ago)

        9end
        let!(:newer_treating) do
            FactoryGirl.create(:treating, requestor: @user, created_at: 1.hour.ago)
            FactoryGirl.create(:treating, requestee: @user, created_at: 1.hour.ago)
        end

        it "should have the right treatings in the right order" do
            @sent_treating = requestor.sent_treatings.build(intro: "Lorem ipsum")
            @sent_treating.requestee = requestee

            @received_treating = requestee.received_treatings.build(intro: "Lorem ipsum")
        @received_treating.requestor = requestor

            requestor.sent_treatings.should == [newer_treating, older_treating]
            requestee.received_treatings.should == [newer_treating, older_treating]
        end

I'm not sure why 'requestee' would be blank here and could use some help. Thank you.

EDIT: factory is below, thanks!

FactoryGirl.define do
    factory :user do
        sequence(:name) { |n| "Person #{n}" }
        sequence(:email) { |n| "person_#{n}@example.com"}
        password "foobar"
        password_confirmation "foobar"

        factory :admin do
            admin true
        end
    end

    factory :treating do
    intro "Lorem ipsum"
  end

end

(I've tried to add 'user', 'requestor', and 'requestee' below 'intro' in the :treating factory, but still no success). When I add 'user' in the factory file (below 'intro "Lorem ipsum"), I get the following error:

1) User treating associations should have the right treatings in the right order
     Failure/Error: FactoryGirl.create(:treating, requestor: @user, created_at: 1.day.ago)
     NoMethodError:
       undefined method `user=' for #<Treating:0x00000104fa0668>
     # ./spec/models/user_spec.rb:143:in `block (3 levels) in <top (required)>'

When I add 'requestor' and 'requestee' to the factory instead of user (and in addition to use), I get the following error:

Failures:

  1) User treating associations should have the right treatings in the right order
     Failure/Error: FactoryGirl.create(:treating, requestor: @user, created_at: 1.day.ago)
     ArgumentError:
       Trait not registered: requestee

Upvotes: 2

Views: 5057

Answers (2)

po.studio
po.studio

Reputation: 4127

here's the fix.

factories.rb needs aliases mentioned on the :user trait line as

FactoryGirl.define do

  factory :user, aliases: [:requestor, :requestee] do
    sequence(:name) { |n| "Person #{n}" }
    sequence(:email) { |n| "person_#{n}@example.com"}
    password "foobar"
    password_confirmation "foobar"

    factory :admin do
      admin true
    end
  end

  factory :treating do
    intro "Lorem ipsum"
    requestor
    requestee
  end

end

finally, the "treating associations" test needs to have older/newer received/sent treatings (4 variants) broken out as:

describe "treating associations" do
  before { @user.save }
  let!(:older_sent_treating) do
    FactoryGirl.create(:treating, requestor: @user, created_at: 1.day.ago)
  end
  let!(:older_received_treating) do
    FactoryGirl.create(:treating, requestee: @user, created_at: 1.day.ago)
  end
  let!(:newer_sent_treating) do
    FactoryGirl.create(:treating, requestor: @user, created_at: 1.hour.ago)
  end
  let!(:newer_received_treating) do
    FactoryGirl.create(:treating, requestee: @user, created_at: 1.hour.ago)
  end       

  it "should have the right treatings in the right order" do
    @user.sent_treatings.should == [newer_sent_treating, older_sent_treating]
    @user.received_treatings.should == [newer_received_treating, older_received_treating]
  end
end

then the tests should pass. thanks!

Upvotes: 1

DVG
DVG

Reputation: 17470

The problem is that your Treating Factory does not have the requestor and requestee defined, and in addition, you need to tell FactoryGirl that requestor and requestee are aliases for a User

factory :user, :aliases => [:requestor, :requestee]  do
    sequence(:name) { |n| "Person #{n}" }
    sequence(:email) { |n| "person_#{n}@example.com"}
    password "foobar"
    password_confirmation "foobar"

    factory :admin do
        admin true
    end
end

factory :treating do
    intro "Lorem ipsum"
    requestor
    requestee
end

Upvotes: 1

Related Questions