Jared Beck
Jared Beck

Reputation: 17538

How to use factory_bot to build objects that lack accessor methods?

Given a data model that lacks accessor methods,

class Person
  attr_reader :name # but NO attr_accessor
  def initialize(name)
    @name = name
  end
end

FactoryBot.define do
  factory :person do
    name { 'Grace' }
  end
end

How can I use factory_bot to build a Person? If we try build :person we get:

NoMethodError .. undefined method `name='

I wrote a custom build strategy which works, but I am not pleased with it because I had to use instance_variable_get to access private library objects.

class BuildNew
  def association(runner)
    runner.run
  end

  # @param evaluation [FactoryBot::Evaluation]
  def result(evaluation)
    attributes = evaluation.hash
    model_class = evaluation.instance_variable_get(:@attribute_assigner).send(:build_class_instance).class
    model_class.new(attributes)
  end
end
FactoryBot.register_strategy(:build_new, BuildNew)

Upvotes: 2

Views: 149

Answers (1)

Jared Beck
Jared Beck

Reputation: 17538

It seems the custom build strategy was unnecessary. This can be done much more simply using initialize_with.

FactoryBot.define do
  factory :person do
    initialize_with { new(attributes) }
    name { 'Grace' }
  end
end

Upvotes: 2

Related Questions