无法从 RoR 上的帮助文件中定义的 类 调用帮助方法

Cannot invoke helper methods from classes defined within a helper file on RoR

我试图创建一个小辅助方法,让我更容易在 rails

上使用 ui-kit 创建表单
# app/helpers/form_helper.rb
module FormHelper
  def styled_form_for(record)
    form_for record do |form|
      builder = StyledFormBuilder.new(form)

      yield form, builder
    end
  end

  class StyledFormBuilder
    def initialize(form)
      @form = form
      @obj = form.object
    end

    def text_field(field, **props)
      styled_field :field do
        @form.text_field field, class: ['uk-input', @obj.errors[field].any? && 'uk-form-danger', *props.class],
                                **props
      end
    end

    private

    def styled_field(field)
      errors = @form.object.errors[field].map do |error_message|
        tag.span error_message, class: 'uk-text-danger'
      end

      tag.div class: 'uk-margin' do
        "
        #{@form.label(field, class: 'uk-form-label')}
        #{yield}
        #{errors.join(tag.br)}
        ".html_safe
      end
    end
  end
end

但是当我 运行 这个我得到错误 NameError - undefined local variable or method 'tag' for #<FormHelper::StyledFormBuilder:0x00007ffa08141220> 有没有办法在辅助模块中创建一个 class 来访问其他辅助方法?如果不是,我应该如何“正确”地执行此操作?

您需要将视图上下文传递到 class:

# app/helpers/form_helper.rb
module FormHelper
  def styled_form_for(record)
    form_for record do |form|
      builder = StyledFormBuilder.new(form, context: self)

      yield form, builder
    end
  end

  class StyledFormBuilder
    
    def initialize(form, context:)
      @form = form
      @obj = form.object
      @context = context
    end

    def text_field(field, **props)
      styled_field :field do
        @form.text_field field, class: ['uk-input', @obj.errors[field].any? && 'uk-form-danger', *props.class],
                                **props
      end
    end

    private

    def styled_field(field)
      errors = @form.object.errors[field].map do |error_message|
        @context.tag.span error_message, class: 'uk-text-danger'
      end

      @context.tag.div class: 'uk-margin' do
        "
        #{@form.label(field, class: 'uk-form-label')}
        #{yield}
        #{errors.join(tag.br)}
        ".html_safe
      end
    end
  end
end

视图上下文是所有视图助手和您的助手混入的上下文,它是渲染视图时的隐式自身。