ruby-on-railsruby-on-rails-5.2simple-form-for

Simple_form with Form Object missing Mapping


I am using simple_form_for

<%= simple_form_for( @form_object, url: wizard_path, :method => :put) do |f| %>
    <%= f.input :website %>
    <%= f.submit %>
  </div>
<% end %>

However, I am also using a Form Object

  class Base
    include ActiveModel::Model
    # Validations
    # Delegations
    # Initializer
   end

My issue is that my inputs are not mapping to my database columns, so https://github.com/plataformatec/simple_form#available-input-types-and-defaults-for-each-column-type

None of these show up ,and can I create custom mappings.

How can I allow Simple_form to see my column types and work correctly?

If I check the class of my delegated fields, they seem to show as :string or :integer, etc.


Solution

  • simple_form uses 2 methods to determine the input type field mapping from a standard model (type_for_attribute and has_attribute?). Source

    Since you are wrapping the model in another layer but still want the inference that simple_form provides you just need to delegate these calls to the original model via

    class Wrapper
      include ActiveModel::Model
      attr_reader :model
      delegate :type_for_attribute, :has_attribute?, to: :model
      def initialize(model) 
        @model = model
      end
    end
    

    However if you were not wrapping the model you would need to define these methods yourself such as (using the new rails 5.2 Attribute API)

    class NonWrapper
      include ActiveModel::Model
      include ActiveModel::Attributes
    
      attribute :name, :string
    
      def type_for_attribute(name)
        self.class.attribute_types[name] 
      end 
      def has_attribute?(name)
        attributes.key?(name.to_s)
      end
    end
    

    Example

    a = NonWrapper.new(name: 'engineersmnky') 
    a.has_attribute?(:name)
    #=> true
    a.type_for_attribute(:name)
    #=>  => #<ActiveModel::Type::Value:0x00007fffcdeda790 @precision=nil, @scale=nil, @limit=nil>
    

    Note other additions may be required for a form object like this to work with simple_form. This answer simply explains how to handle the input mapping inference