ruby-on-railsrspecfabrication-gem

How do you fabricate objects with has_many associations that can be queried in rspec?


I have this schema that I want to test in rspec.

class Question
  has_many :choices
end

class Choice
  belongs_to :question
  validates_presence_of :question
end

This doesn't seem to work:

Fabricator(:question) do
  text { sequence(:text) { |i| "my question#{i}" } }
  choices(count: 2) { Fabricate(:choice, question: question)}
end

Nor this:

Fabricator(:question) do
  text { sequence(:text) { |i| "my question#{i}" } }

  before_save do |question|
    choices(count: 2) { Fabricate(:choice, question: question)}
  end
end

The problem I'm having is if I construct the fabrication like this:

Fabricator(:question) do 
  text "question"
end
question = Fabricate(:question)
choice_a = Fabricate(:choice, question: question)
choice_b = Fabricate(:choice, question: question)
(question.choices == nil)  #this is true

In my rspec I need to query question.choices.


Solution

  • You should be able to just use the shorthand in this instance.

    Fabricator(:question) do
      choices(count: 2)
    end
    

    Fabrication will automatically build out the correct association tree and let ActiveRecord do its thing under the hood to associate them in the database. The object you get back from that call should be fully persisted and queryable.

    If you needed to override values in choices you could do it like this.

    Fabricator(:question) do
      choices(count: 2) do
        # Specify a nil question here because ActiveRecord will fill it in for you when it saves the whole tree.
        Fabricate(:choice, question: nil, text: 'some alternate text')
      end
    end