Search code examples
ruby-on-railsrubyreform

field_with_errors not being applied on reform form object


I am using the reform gem to create a form object. Typically in rails: when a validation fails on a form: the field_with_errors class wraps the label and input of the invalid fields. This is not occurring in my reform form object.

Here is the class for the form object:

# app/forms/signup_form.rb
class SignupForm < Reform::Form
  include Reform::Form::ActiveRecord
  include Composition

  model :user, on: :user 

  property :id,               on: :user
  property :name,             on: :user

  property :blog_id,          on: :blog, from: :id
  property :user_id,          on: :blog
  property :title,            on: :blog

  validates :name, presence: true
  validates :title, presence: true

end

And here is the actual form:

# app/views/users/_form.html.erb
<%= form_for(signup_form, url: signup_form_path(signup_form.model[:user]), method: signup_form_method(signup_form.model[:user])) do |form| %>

  <% if signup_form.errors.size > 0 %>
    <div>
      <p><%= pluralize(signup_form.errors.size, "error") %> prohibited the data from persisting</p>
      <p>There were problems with the following fields:</p>
      <ul>
        <% signup_form.errors.full_messages.each do |msg| %>
          <li><%= msg %></li>
        <% end %>
      </ul>
    </div>
  <% end %>

  <%= form.hidden_field(:user_id, value: form.object.user_id) %>

  <div class="field">
    <%= form.label :name, "* Name" %>
    <%= form.text_field :name %>
  </div>

  <div class="field">
    <%= form.label :title, "* Title" %>
    <%= form.text_field :title %>
  </div>

  <div class="actions">
    <%= form.submit %>
  </div>
<% end %>

Here is what the form looks like prior to being submitted:

prior submissions

If I click the Create User button without filling anything out, it fails because the Name and Title fields are required. It does properly fail, but the invalid labels and fields are not wrapped with field_with_errors and thus are not styled with the rails default field_with_errors styling. It looks like this:

after submission


Applying the approved answer for a complete code solution of this question:

<div class="field <%= form_obj_field_with_errors(form.object.errors[:name].join(',')) %>">
  <%= form.label :name, "* Name" %>
  <%= form.text_field :name %>
</div>

<div class="field <%= form_obj_field_with_errors(form.object.errors[:title].join(',')) %>">
  <%= form.label :title, "* Title" %>
  <%= form.text_field :title %>
</div>

And here is the helper:

def form_obj_field_with_errors(error_msg)
  return unless error_msg.present?
  return 'field_with_errors'
end

Update!!!

It turns out that the above solution is unnecessary. Reform does properly apply field_with_errors. My error was that I was using the latest, unstable version of reform in my rails project.

Previously I specified this gem to bring reform into my rails project:

gem 'reform-rails', '0.2.0rc1'

That version was unstable. I switched to the latest stable version, and it all worked as expected. No need to add field_with_errors by hand:

gem 'reform-rails', '~> 0.1.7'

Solution

  • The easiest solution is to use simple_form_for gem which will create the entire component (label, input and inline error message):

    <%= simple_form_for signup_form do |form| %>
      <%= form.input :name %>
    

    Otherwise you need to add the inline error messages yourself, for example:

    <%= form.object.errors[:name].join(', ') %>