Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to carry over form field values after an invalid submit, using only ActiveModel?

It appears to be normal functionality for a Rails form that has been submitted with invalid data to display error messages and repopulate the form with the invalid data. At least, all my Active Record managed resources work this way.

However, I have a virtual resource/model that is not an Active Record but instead makes use Rails 3 ActiveModel along the lines of Railscast #219.

Everything works as I expect, apart from when submission fails. The re-rendered form is empty. Error messages are displayed as normal.

Which part of Rails is responsible for this functionality and how do I include it in my ActiveModel based resource?

To clarify:

  1. A user completes and submits a form containing two values.
  2. Validation fails because one or more of these values is invalid.
  3. The controller re-renders the 'new' view for the model.
  4. The re-rendered form contains error messages.
  5. The re-rendered form is pre-populated with the two invalid data values.

It is step 5 that I do not understand and which is not happening with my Active Model resource, despite having near identical controller code and identical view code, to my Active Record resources.

The code (as requested)

Controller:

def new
  @contact = Contact.new
end

def create
  @contact = Contact.new(params[:contact])

  if @contact.valid?
    AgentMailer.contact_email(@contact).deliver
    redirect_to "/contact", notice: 'Your request was successful.' 
  else
    #TODO Figure out why data from an invalid submission does not carry over
    render action: "new"
  end
end

View:

<%= form_for(@contact, :html => {:class => "new_contact custom"}) do |f| %>
  <% if @contact.errors.any? %>
    ...
  <% end %>

  ...

  <%= f.label :name %>
  <%= f.text_field :name, options = {placeholder: "Enter name here"} %>     

  ...
<% end %>
like image 535
Anthony H Avatar asked Jan 30 '26 05:01

Anthony H


1 Answers

The scaffold command creates form partials that include the error messages you mention. No magic here, just a view that is rendering errors from the model if they exist. You can use the errors ERB code from below as a template for how to add error messages to other views.

rails new test_project
cd test_project
rails generate scaffold users name

Look at app/views/users/_form.html.erb

 <% if @user.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:</h2>

      <ul>
      <% @user.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>
like image 73
Puhlze Avatar answered Jan 31 '26 21:01

Puhlze