John Abraham
John Abraham

Reputation: 18771

how does form_for know the difference when submitting :new :edit

I've generated a scaffold, let's call it scaffold test. Within that scaffold, I've got a _form.html.erb thats being render for action's :new => :create and :edit => :update

Rails does a lot of magic sometimes and I cannot figure out how the form_for knows how to call the proper :action when pressing submit between :new and :edit

Scaffolded Form

<%= form_for(@test) do |f| %>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

vs. Un-scaffolded Form

 <% form_for @test :url => {:action => "new"}, :method => "post" do |f| %>
       <%= f.submit %>
 <% end %>

#Edit template

Editing test

<%= render 'form' %>

#New template

New test

<%= render 'form' %>

As you can see theres no difference between the forms How can both templates render the same form but use different actions?

Upvotes: 34

Views: 16954

Answers (3)

zeantsoi
zeantsoi

Reputation: 26193

If the @test instance variable is instantiated via the Test.new class method, then the create method is executed. If @test is an instance of Test that exists in the database, the update method is executed.

In other words:

# app/controllers/tests_controller.rb
def new
    @test = Test.new
end

<%= form_for(@test) |do| %> yields a block that is sent to the create controller method.

If, instead:

# app/controllers/tests_controller.rb
def edit
    @test = Test.find(params[:id])
end

<%= form_for(@test) |do| %> yields a block that is sent to the update controller method.

UPDATE:

The precise function that Rails uses to recognize whether or not a record is new is the persisted? method.

Upvotes: 4

shweta
shweta

Reputation: 8169

It checks if the record is new or not.

@test.new_record? # if true then create action else update action

Upvotes: 10

Logan Serman
Logan Serman

Reputation: 29860

It checks @test.persisted? If it is persisted then it is an edit form. If it isn't, it is a new form.

Upvotes: 69

Related Questions