developer098
developer098

Reputation: 843

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

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.

Upvotes: 9

Views: 5942

Answers (4)

spickermann
spickermann

Reputation: 106812

f.object refers to the object that was passed as an argument to the form builder form_for method in this line <%= form_for(@section) do |f| %> in the view.

In your example, f.object returns @section.

Upvotes: 8

BenKoshy
BenKoshy

Reputation: 35595

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.

Upvotes: 0

Eric Duminil
Eric Duminil

Reputation: 54223

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
      ...

Upvotes: 3

Alexander Luna
Alexander Luna

Reputation: 5449

"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.

Upvotes: 3

Related Questions