I'm giving Draper a try as an alternative to helpers. I get the cases where I am just formatting the information. But what about interacting with the Rails form builder. For example if I wanted to output a string or a select box depending on some context. Do I pass the form builder as an argument. So in my decorator:
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
Then in my view:
= simple_form_for user do |form|
...
= user.role_or_select_on form
...
Is there a more elegant method?
I think I found a somewhat elegant solution to this. I created the following module and mixed it into my decorators:
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
Now my view can be this:
= user.form do
= user.input :name
= user.input :email
= user.role_or_select
The input
method is proxied off to the form builder. The role_or_select is defined in my helper to look something like this:
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
This even allows me to do things like add the form options in the decorator. For example adding the following to my UserDecorator will turn off the auto-complete:
def form options={}
options[:html] ||= {}
options[:html][:autocomplete] = 'off'
super options
end
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.