как form_for знать разницу при отправке: new: edit

Я сгенерировал эшафот, позвольте назвать его scaffold. Внутри этого эшафота у меня есть _form.html.erb, который отображается для действия: new =>: create and: edit =>: update

Rails иногда делает много магии, и я не могу понять, как form_for знает, как вызвать правильное: действие при нажатии submit между: new и: edit

Форма лесов

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


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

против формы без леса

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

Изменить шаблон

<h1>Editing test</h1>

<%= render 'form' %>

Новый шаблон

<h1>New test</h1>

<%= render 'form' %>

Как вы можете видеть, нет никакой разницы между формами. Как оба шаблона могут отображать одну и ту же форму, но использовать разные действия?

Ответ 1

Он проверяет @test.persisted? Если он сохраняется, это форма редактирования. Если это не так, это новая форма.

Ответ 2

Он проверяет, является ли запись новой или нет.

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

Ответ 3

Если @test переменная экземпляра конкретизируется через Test.new метод класса, то create метод выполняется. Если @test является экземпляром Test который существует в базе данных, выполняется метод update.

Другими словами:

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

<%= form_for(@test) |do| %> <%= form_for(@test) |do| %> дает блок, который отправляется методу create.

Если вместо этого:

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

<%= form_for(@test) |do| %> <%= form_for(@test) |do| %> дает блок, который отправляется методу контроллера update.

ОБНОВЛЕНИЕ:

Точная функция, которую Rails использует для распознавания новой записи, - это persisted? метод.