What does f.object do in the Rails form builder?
Asked Answered
W

4

8

I am learning Rails 5.0 from a tutorial, and in that tutorial it uses f.object, which I am unfamiliar with. The f.object is being passed into ERb, into a method that handles error processing.

I know that f is the object/instance of a record being passed into the form. But what I don't understand is f.object.

edit.html.erb (file with form):

<%= form_for(@section) do |f| %>

<%= error_messages_for(f.object) %>
  <table summary="Subject form fields">
    <tr>
      <th>Name</th>
      <td><%= f.text_field(:name) %></td>
    </tr>
    <tr>
      <th>Position</th>
      <td><%= f.select(:position, 1..@subject_count) %></td>
    </tr>
   </table>
<% end %>

There is no HTML form element known as object, and that's what usually goes after the f., so really miffed on what it could be.

Wikiup answered 9/1, 2017 at 21:3 Comment(0)
C
7

f.object refers to the object passed as an argument to the form_for method.

In your example f.object returns @section.

Crow answered 9/1, 2017 at 21:18 Comment(0)
C
3

"f" is the local variable used in the form block. The form contains an object (@section) and if an error occurs you pass that object to an error partial that checks if there are any errors and renders the error messages the object created for you. In my form I usually add an error partial like this:

  <%= render "shared/error_messages", object: f.object %>

In your error partial it looks somewhat like this (_error_messages.html.erb):

<% if object.errors.any? %>   # object in this case is @section
  <ul>
    <% object.errors.full_messages.each do |msg| %>
    <li><%= msg %></li>
    <% end %>
  </ul>
</div>
<% end %> 

It really is just a way to pass the form's object with is errors to a partial to display it properly. There is no html involved.

Culver answered 9/1, 2017 at 21:19 Comment(0)
D
3

As explained in these two questions :

f.object inside the form_for returns the model object the form is using.

In this case : @section

The code is here, inside rails/actionview/lib/action_view/helpers/active_model_helper.rb, apparently without comments :

    module ActiveModelInstanceTag
      def object
        @active_model_object ||= begin
          object = super
          object.respond_to?(:to_model) ? object.to_model : object
        end
      end
      ...
Duplication answered 9/1, 2017 at 21:20 Comment(0)
W
0

Summary: f.object is the record you are using: @section

ok, you're still here? Here is a little bit more of an explanation as to what is going on, after I quickly glanced at the source code:

The f is a form builder object. The form builder has an @object instance variable. If you are using a record in form_for, then the record will become @object. If you are using a string when you are using form_for, then f.object will be should be nil. But in your case, you are using a record, so f.object will be a record.

With the utmost respect, I could not follow the execution path in the currently accepted answer. When you use the form_for method, the object passed in is simply the first parameter passed in, and that is what is used to create the form_builder object, which is then used to instantiate the @object variable.

Wold answered 9/4, 2020 at 2:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.