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