Search code examples
formtasticrails-3.1enumerated-types

Formtastic ~> 2.0.2 and enumerated_attribute gem, Rails 3.1.1


I used enumerated_attribute with formtastic ~> 1.2.3 with "monkey patch" for field :as => :enum and everything worked fine.

But when I updated formtastic to 2.0.2 version appeared an error with message "Formtastic::UnknownInputError".

For more details here is patch, that was added to /initialisers/formtastic.rb:

module Formtastic #:nodoc:
  class SemanticFormBuilder #:nodoc:
    def enum_input(method, options)
      unless options[:collection]
        enum = @object.enums(method.to_sym)
        choices = enum ? enum.select_options : []
        options[:collection] = choices
      end
      if (value = @object.__send__(method.to_sym))
        options[:selected] ||= value.to_s
      else
        options[:include_blank] ||= true
      end
      select_input(method, options)
    end
  end
end

P.S. I tried to change SemanticFormBuilder to FormBuilder (as I understood from new formtastic documentation there was such change for all custom inputs), but I was still getting error

Maybe anybody already used these gems together successfully?


Solution

  • They way custom fields are defined has changed completely in Formtastic 2.x

    You need to subclass the internal Formtastic classes to get what you want. A select input would look something like this:

    module FormtasticExtensions
      class EnumeratedInput < Formtastic::Inputs::SelectInput
        def collection
          # programmatically build an array of options in here and return them
          # they should be in this format:
          # [['name', 'value'],['name2', 'value2']]
        end
      end
    end
    

    Include the module in the Formtastic initializer:

    include FormtasticExtensions

    and this will give you a field :as => :enumerated and you should be good to go. In my case (some other custom field) it selects the current option, but you may need to tweak the code for yours to work.

    You could also just pass the collection in:

    f.input :thing, :as => :select, :collection => your_collection, :label_method => :your_name, :value_method => :your_id