0

我正在尝试 Draper 作为助手的替代品。我得到了我只是格式化信息的情况。但是如何与 Rails 表单构建器交互呢?例如,如果我想根据某些上下文输出字符串或选择框。我是否将表单构建器作为参数传递。所以在我的装饰器中:

def role_or_select form
  available_roles = h.policy_scope User::ROLES
  if available_roles.include? role
    form.input :role, collection: available_roles, include_blank: false
  else
    role
  end
end

然后在我看来:

= simple_form_for user do |form|
  ...
  = user.role_or_select_on form
  ...

有没有更优雅的方法?

4

1 回答 1

0

我想我找到了一个有点优雅的解决方案。我创建了以下模块并将其混合到我的装饰器中:

module FormDecoration

  def form options={}, &blk
    h.simple_form_for model, options do |builder|
      @form_builder = builder
      blk[builder]
    end
  ensure
    @form_builder = nil
  end

  def method_missing meth, *args, &blk
    if @form_builder && @form_builder.respond_to?(meth)
      @form_builder.public_send meth, *args, &blk
    else
      super
    end
  end

  def respond_to? meth
    (@form_builder && @form_builder.respond_to?(meth)) || super
  end
end

现在我的观点可以是这样的:

= user.form do
  = user.input :name
  = user.input :email
  = user.role_or_select

input方法被代理到表单构建器。role_or_select 在我的助手中定义如下:

  def role_or_select
    available_roles = h.policy_scope User::ROLES
    if available_roles.include? object.role
      input :role, collection: available_roles, include_blank: false
    else
      object.role
    end
  end

这甚至允许我做一些事情,比如在装饰器中添加表单选项。例如,将以下内容添加到我的 UserDecorator 将关闭自动完成功能:

def form options={}
  options[:html] ||= {}
  options[:html][:autocomplete] = 'off'
  super options
end
于 2014-12-13T02:52:06.797 回答