Skip to content

anonymize fails in Rails initializers: constantize runs before autoloading #25

@Spone

Description

@Spone

Problem

config.anonymize("User") fails with NameError: uninitialized constant User when used in a Rails initializer (config/initializers/evil_seed.rb), because Anonymizer#initialize calls model_name.constantize immediately at config time — before Rails autoloading has loaded the model.

NameError: uninitialized constant User (NameError)
  evil-seed/lib/evil_seed/anonymizer.rb:20:in 'EvilSeed::Anonymizer#initialize'
  evil-seed/lib/evil_seed/configuration.rb:38:in 'EvilSeed::Configuration#anonymize'
  config/initializers/evil_seed.rb

Root cause

Anonymizer#initialize eagerly constantizes the model name:

# lib/evil_seed/anonymizer.rb
def initialize(model_name, &block)
  @model_class = model_name.constantize  # <-- runs at config time
  @changers = {}
  instance_eval(&block)
end

This is only needed for method_missing to validate column names. By contrast, customize works fine because it just stores a lambda without calling constantize.

Suggested fix

Lazily resolve the model class:

def initialize(model_name, &block)
  @model_name = model_name
  @changers = {}
  instance_eval(&block)
end

def model_class
  @model_class ||= @model_name.constantize
end

This defers the constantize call until the anonymizer is actually used (at dump time), when all models are loaded.

Workaround

Use customize instead of anonymize:

config.customize("User") do |u|
  u["email"] = Faker::Internet.email
  u["name"]  = Faker::Internet.username
end

Environment

  • evil-seed 0.7.0
  • Rails 8.1
  • Ruby 4.0.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions