3

Я новичок. Я прочитал документацию по API. Но до сих пор не понимаю, как работает form_for.как form_for работает в Ruby on Rails

Во-первых, из Ruby On Rails Tutorial, форма для кнопки наблюдения:

<%= form_for(current_user.relationships.build(followed_id: @user.id)) do |f| %> 
    <div><%= f.hidden_field :followed_id %></div> 
    <%= f.submit "Follow", class: "btn btn-large btn-primary" %> 
<% end %> 

Я понимаю current_user.relationships.build(followed_id: @user.id) означает новый рекорд. Но почему мы не можем просто отправить и запустить контроллер, чтобы сохранить запись без hidden_field? Почему нам все еще нужно отправлять follow_id контроллеру?

Во-вторых, в hidden_field, что означает :followed_id? Я считаю, что это символ, т. Е. Он равен только «follow_id», а не переменной id. Если это только имя поля ввода, то каково его значение?

В-третьих, как form_for знать, куда отправить отправку? Какой контроллер и действие отправит form_for?

В-четвертых, как params Работает с form_for? В этом случае с кнопкой мыши, params[:relationship][:followed_id] вернет @user.id в контроллер. Как он знает, что первый хеш-атрибут - :relationship? Мы не упомянули form_for :relationship или form_for @relationship.

Я знаю, что эти вопросы могут быть очень глупыми, но я действительно застрял. Любая помощь будет оценена.

ответ

3

Я не делал этого учебника, так что подумайте, если я не отвечу непосредственно на ваш вопрос.

Взгляните на rails guide about form helpers и подробно объясните свои вопросы, возможно, более четко, чем я могу.

form_for(path/to/your/controller/action) является вспомогательным методом для создания элементов HTML-формы с URL-адресом для запроса POST или GET. Помощник знает, должна ли она быть новая запись или запись обновления, основанная на том, что вы просите сделать в действии вашего контроллера.

Например В контроллере

def new 
    @my_instance_variable = Myobject.new 
end 

На ваш взгляд new.html.erb

<%= form_for @my_instance_variable do |f| %> 
... 
<% end %> 

В вашем случае логика непосредственно написанному в помощнике, и вы также можете напрямую писать

<%= form_for Myobject.new %> 

Оба результата приведут к следующему html

<form action="/myobjects/new" method="post"> 
# in this case rails knows its a `POST` request because the route new action 
# is by default a POST request. You can check these routes and their request 
# by using `rake routes` in terminal. 

Тогда hidden_field еще один помощник, чтобы содержать значение, в вашем случае @user.id, который будет передан в качестве параметра затем сохраняются как создать или обновить действие для данного объекта. Причина, по которой он не добавляет значение в тег скрытого поля, состоит в том, что у вас уже есть ассоциация модели, которая знает идентификатор пользователя, поскольку ссылка формы использует метод сборки с идентификатором пользователя.

Последняя часть, которую вы должны понять form_for ссылку логику

current_user.relationships 
# implies the association of the current_user has many relationships 
current_user.relationships.build 
# .build is a method to populate a new object that can be save as a new record 
# means you will create a new relationship record by populating the user_id 
# column with the current_user.id and the followed_id with the target @user.id 
+0

Большое вам спасибо. Это отличный ответ. Но я все еще смущен. Во-первых, если вход после «form_for» - это путь. Затем form_for Myobject.new и Myobject.build должны направить нас к действию «новый» и «построить»? Но вместо этого он направляет меня к действию «творить». В любом случае, это не большая проблема, пока я понимаю, как он перенаправляет меня на правильный контроллер. –

+0

в 'form_for current_user.relationships.build (follow_id: @ user.id)', 'form_for' нужна только первая часть' current_user.relationships.build'. Это означает, что последняя часть '(follow_id: @ user.id)' не нужна, я прав? Или он играет некоторые роли, чтобы помочь значение hidden_field? Я думаю, что до сих пор не получаю ответа на мой первый и второй вопрос. Может быть, мне нужно больше времени, чтобы прочитать Rails Guides, которые вы предложили в первую очередь. Спасибо –

+1

Вам нужно указать рельсы, что вы хотите построить, с соответствующей информацией, так что да, вам нужна последняя часть. Метод build используется, когда существует ассоциация модели. Вы можете проверить [api] (http://api.rubyonrails.org/classes/ActiveRecord/Associations/CollectionProxy.html#method-i-build). Если вы не добавите @ user.id, то follow_id приведет к нулю. –

1

После прочтения книги Рельсы 4 Way, я понимаю form_for лучше.

11.9.1.5 Отображение существующих значений. Если вы редактировали существующий экземпляр Person, значения атрибута этого объекта были бы заполнены в форму .

таким образом, когда мы строим отношения с помощью current_user.relationships.build(followed_id: @user.id), экземпляр отношения будут созданы и получить атрибут followed_id. Таким образом, вместо того, чтобы «создавать» отношения, мы фактически редактируем отношения по форме.

Затем Rails узнает, что вы редактируете и загружаете существующий атрибут «follow_id» в поле. Поэтому нам не нужно присваивать значение полю, например, f.hidden_field :followed_id, value: @user.id.

И причина, почему мы должны использовать поле для передачи follow_id в params, потому что HTTP-сервер не имеет статуса, он не помнит, что вы создаете отношения, с которыми пользователь.

Одним из преимуществ написания form_for current_user.relationships.build(followed_id: @user.id) вместо стандартного form_for @relationship это нам не нужно писать «если условие» в контроллере, как это:

unless current_user.nil? 
    if current_user.following?(@user) 
    @relationship=current_user.relationships.find_by(followed_id: @user.id) 
    else 
    @relationship=current_user.relationships.new 
    end 
end 

PARAMS будет отправлено на контроллер, который принадлежит модель экземпляра. «post» метод будет действовать для создания, «удалить» будет уничтожено, «патч» пойдет на обновление и т. д.

params будет хешем с другим хэшем внутри, как {instace_name: {field_1: value1, поле_2: значение2}} или полные параметры, указанные ниже

Parameters: {"utf8"=>"✓", 
    "authenticity_token"=>"afl+6u3J/2meoHtve69q+tD9gPc3/QUsHCqPh85Z4WU=", 
    "person"=>{"first_name"=>"William", "last_name"=>"Smith"}, 
    "commit"=>"Create"} 
Смежные вопросы