Sha256: ade85ac593fffac4e8da03594a5fc768bc0dd4f5bb21e117d6c7df878c3a4f3d

Contents?: true

Size: 1.9 KB

Versions: 6

Compression:

Stored size: 1.9 KB

Contents

module FactoryBurgers
  # Build resources from specified factories, traits, and attributes
  class Builder
    attr_reader :owner

    # `owner` is an optional resource that we can attach new resources to
    # E.g. a `User` for whom we wish to build a `Post`.
    def initialize(owner = nil)
      @owner = owner
    end

    # TODO: clean up method signature
    def build(factory, traits, attributes, as: nil) # rubocop:disable Naming/MethodParameterName; as is a good name here
      resource = insistently do
        FactoryBot.create(factory, *traits, attributes)
      end
      update_assocation_to_owner(as, resource) if owner && as

      return resource
    end

    private

    def update_assocation_to_owner(association_name, resource)
      reflection = get_owner_association(association_name)
      case reflection
      when ActiveRecord::Reflection::BelongsToReflection, ActiveRecord::Reflection::HasOneReflection
        # This will update the foreign key on `resource` for has_one.
        owner.update!(association_name => resource)
      when ActiveRecord::Reflection::HasManyReflection
        # This will update the foreign key on `resource`.
        owner.public_send(association_name) << resource
      else
        invalid_association(reflection)
      end
    end

    def get_owner_association(name)
      owner.class.reflections[name.to_s] or raise "Could not find association named #{name}"
    end

    # Brute force through sequences (e.g. account name) to overcome uniqueness validations
    def insistently(tries = 30)
      tries.times do |attempt|
        return yield
      rescue ActiveRecord::RecordInvalid
        raise if attempt >= tries - 1
      end
    end

    def invalid_association(reflection)
      msg = "#{reflection.class} association #{reflection.name} on #{reflection.active_record.name} is not supported."
      raise FactoryBurgers::Errors::InvalidAssociationError, msg
    end
  end
end

Version data entries

6 entries across 6 versions & 1 rubygems

Version Path
factory_burgers-1.1.3 lib/factory_burgers/builder.rb
factory_burgers-1.1.2 lib/factory_burgers/builder.rb
factory_burgers-1.1.1 lib/factory_burgers/builder.rb
factory_burgers-1.1.0 lib/factory_burgers/builder.rb
factory_burgers-1.0.0 lib/factory_burgers/builder.rb
factory_burgers-0.1.5 lib/factory_burgers/builder.rb