How to display validation error messages with Simple_form but without model?

Fred Perrin picture Fred Perrin · Jun 7, 2014 · Viewed 10.5k times · Source

I use Simple_form in my Rails 4 application.

How can I display error messages in a view that is not tied to a model ?

I want to have the same result than in other views based on models.

For now, this is the code in the view :

<%= simple_form_for(:registration, html: { role: 'form' }, :url => registrations_path) do |f| %>

  <%= f.error_notification %>

  <%= f.input :name, :required => true, :autofocus => true %>
  <%= f.input :email, :required => true %>
  <%= f.input :password, :required => true %>
  <%= f.input :password_confirmation, :required => true %>

  <%= f.button :submit %>

<% end %>

In a 'normal' view (i.e. with a model) the line <%= f.error_notification %> display errors.

What should I do in my controller to initialize something used by Simple_form to display errors ?

Thanks

Answer

adailey picture adailey · Sep 16, 2015

Simple Form does not support this functionality "out of the box". But you can add it with a "monkey patch" in an initializer like this (disclaimer - this appears to work for my simple test case but has not been thoroughly tested):

// Put this code in an initializer, perhaps at the top of initializers/simple_form.rb
module SimpleForm
  module Components
    module Errors
      def has_errors?
        has_custom_error? || (object && object.respond_to?(:errors) && errors.present?)
      end

      def errors
        @errors ||= has_custom_error? ? [options[:error]] : (errors_on_attribute + errors_on_association).compact
      end
    end
  end
end

module SimpleForm
  class ErrorNotification
    def has_errors?
      @options[:errors] || (object && object.respond_to?(:errors) && errors.present?)
    end
  end
end

And then you can add errors to your form like this (note you indicate whether to show the error notification by setting 'errors: true', you would have to perform your own check to decide if there are errors present, and add the errors dynamically):

=simple_form_for :your_symbol do |f|
  =f.error_notification errors: true
  =f.input :item1, as: :string, error: "This is an error on item1"
  =f.input :item2, as: :string, error: "This is an error on item2"