{"record":{"id":"75eced70f40784f6","repo":"thoughtbot/factory_bot","slug":"defining-methods-in-blocks-trait-or-factory-is-n","errorCode":null,"errorMessage":"Defining methods in blocks (trait or factory) is not supported (#{name})","messagePattern":"Defining methods in blocks \\(trait or factory\\) is not supported \\(#(.+?)\\)","errorType":"exception","errorClass":"FactoryBot::MethodDefinitionError","httpStatus":null,"severity":"error","filePath":"lib/factory_bot/definition_proxy.rb","lineNumber":34,"sourceCode":"    ].freeze\n\n    (instance_methods + private_instance_methods).each do |method|\n      undef_method(method) unless UNPROXIED_METHODS.include?(method.to_s)\n    end\n\n    delegate :before, :after, :callback, to: :@definition\n\n    attr_reader :child_factories\n\n    def initialize(definition, ignore = false)\n      @definition = definition\n      @ignore = ignore\n      @child_factories = []\n    end\n\n    def singleton_method_added(name)\n      message = \"Defining methods in blocks (trait or factory) is not supported (#{name})\"\n      raise FactoryBot::MethodDefinitionError, message\n    end\n\n    # Adds an attribute to the factory.\n    # The attribute value will be generated \"lazily\"\n    # by calling the block whenever an instance is generated.\n    # The block will not be called if the\n    # attribute is overridden for a specific instance.\n    #\n    # Arguments:\n    # * name: +Symbol+ or +String+\n    #   The name of this attribute. This will be assigned using \"name=\" for\n    #   generated instances.\n    def add_attribute(name, &block)\n      declaration = Declaration::Dynamic.new(name, @ignore, block)\n      @definition.declare_attribute(declaration)\n    end\n\n    def transient(&block)","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/thoughtbot/factory_bot/blob/18ae8b581bf55de681c8adb5f74d32787fd2157f/lib/factory_bot/definition_proxy.rb#L16-L52","documentation":"MethodDefinitionError raised via DefinitionProxy#singleton_method_added (definition_proxy.rb:32-35). Factory, trait, and transient bodies are instance_eval'd against a DefinitionProxy from which almost all methods have been undefined; writing `def something` inside the block defines a singleton method on the proxy, which fires the hook and raises immediately. DSL blocks only accept attribute declarations, so helper methods are rejected.","triggerScenarios":"Inside `factory :user do ... end`, `trait :x do ... end`, or `transient do ... end`, write `def email_domain; 'example.com'; end`. The hook raises at definition (load) time: \"Defining methods in blocks (trait or factory) is not supported (email_domain)\".","commonSituations":"Trying to DRY logic shared by several attribute blocks; developers used to block DSLs (Rake, RSpec) where `def` inside a block works; porting object-mother or fixture code that contained helper methods.","solutions":["Inline the logic into the attribute block, or compute it in a transient attribute that other attributes reference.","Put the helper on the model or in a plain module and call it from the blocks.","For helpers needed inside dynamic blocks, include a module into FactoryBot::SyntaxRunner via an initializer (`FactoryBot::SyntaxRunner.include MyHelpers`).","Use `initialize_with { ... }` to route construction through a builder that encapsulates the logic."],"exampleFix":"# before\nFactoryBot.define do\n  factory :user do\n    def email_domain; 'example.com'; end # raises MethodDefinitionError\n    email { \"user@#{email_domain}\" }\n  end\nend\n\n# after\nFactoryBot.define do\n  factory :user do\n    email { 'user@example.com' } # inline it, or use a model/SyntaxRunner helper\n  end\nend","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":"begin\n  require 'spec/factories'\nrescue FactoryBot::MethodDefinitionError => e\n  # e.message names the method; move the def to the model, a module, or FactoryBot::SyntaxRunner\nend","preventionTips":["Never use `def` inside factory, trait, or transient blocks.","Share helper logic via modules included on the model, or into FactoryBot::SyntaxRunner for use inside dynamic blocks.","Use transient attributes to compute derived values instead of helper methods."],"tags":["ruby","factory-bot","dsl","method-definition"],"backgroundTag":"unsupported-method-definition","analyzedSha":"18ae8b581bf55de681c8adb5f74d32787fd2157f","analyzedAt":"2026-08-21T18:25:33.545Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}