Skip to content

Instantly share code, notes, and snippets.

@denispeplin
Created November 1, 2012 06:25
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save denispeplin/3992175 to your computer and use it in GitHub Desktop.
Save denispeplin/3992175 to your computer and use it in GitHub Desktop.
Add display_filter option to simple_form
module SimpleForm
class FormBuilder < ActionView::Helpers::FormBuilder
# tried to monkey patch without copy'n'pasting, broke associations
def input(attribute_name, options={}, &block)
options = @defaults.deep_dup.deep_merge(options) if @defaults
chosen =
if name = options[:wrapper]
name.respond_to?(:render) ? name : SimpleForm.wrapper(name)
else
wrapper
end
# here display_filter logic begins
display_filter = options.delete(:display_only)
if (! display_filter) || (display_filter && display_filter.include?(attribute_name))
chosen.render find_input(attribute_name, options, &block)
end
end
end
end
@carlosantoniodasilva
Copy link

# A specific form builder to deal with filtering attributes out based on parameters
class StrongParametersFormBuilder < SimpleForm::FormBuilder
  def input(attribute_name, options = {}, &block)
    display_only = options[:display_only]

    super unless display_filter && display_filter.include?(attribute_name)
  end
end

# Form Helper to be used
def strong_parameters_form_for(object, options = {}, &block)
  simple_form_for(object, options.merge(:builder => StrongParametersFormBuilder)), &block)
end

@carlosantoniodasilva
Copy link

There we go:

# Helper
module ApplicationHelper
  # A specific form builder to deal with filtering attributes out based on parameters
  class StrongParametersFormBuilder < SimpleForm::FormBuilder
    def input(attribute_name, *args, &block)
      display_filter = self.options[:display_only]

      super unless display_filter && display_filter.include?(attribute_name)
    end
  end

  # Form Helper to be used
  def strong_parameters_form_for(object, options = {}, &block)
    simple_form_for(object, options.merge(:builder => StrongParametersFormBuilder), &block)
  end
end
# view
<%= strong_parameters_form_for(@topic, display_only: [:name] ) do |f| %>
  <%= f.error_notification %>

  <div class="form-inputs">
    <%= f.input :name %>
    <%= f.input :sticky %>
  </div>

  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>

The issues:

  • We had an options argument in def input, so we need to access self.options to access the builder options instead (I've also changed to *args inside the input definition, since options are not being used there.
  • The argument should be given as display_only: [:name], not inside the :defaults key. If you want to move it inside defaults, you have to access it the same way when calling the form.

I tested the app and it worked fine for me, let me know how it goes.

@denispeplin
Copy link
Author

# display display_only attributes
if display_filter
  super if display_filter.include?(attribute_name)
else
  super
end

Working example here: https://github.com/denispeplin/display_filter_demo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment