Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force FactoryGirl to create parent before creating factory?

I have an Event model that, when saved, updates some attributes on the parent User.

class User
  has_many :events
end

class Event
  belongs_to :user
  before_save :update_user_attributes

  validates :user, presence: true

  def update_user_attributes
    self.user.update_attributes(hash_of_params)
  end
end

This works fine most of the time — a User must exist and be logged in before they can interact with an Event.

But my test suite is causing problems, specifically the event factory.

FactoryGirl.define do
  factory :event do
    user
  end
end

It seems that, due to the order FactoryGirl builds the Event, the User is not available at the time the Event is created, causing update_user_attributes to fail.

This means that

create(:event)
# ActiveRecord::RecordNotSaved:
# Failed to save the record

but

build(:event).save

passes without errors

There are a number of ways I could prevent the error being raised, e.g., check that user.persisted? in the update_user_attributes method, or run the callaback after_save. But my question specifically relates to FactoryGirl.

Given the above factoy, is there a way to force the associated User to be created before creating the Event?

like image 520
Andy Harvey Avatar asked Apr 04 '17 10:04

Andy Harvey


1 Answers

You can write callbacks in FactoryGirl:

FactoryGirl.define do
  factory :event do
    user

    before(:create) do |event|
      create(:user, event_id: event.id)
    end
  end
end

Here is docs link

Also there is an article on thoughtbot about FG callbacks

like image 63
Martin Zinovsky Avatar answered Nov 14 '22 21:11

Martin Zinovsky