Ruby on rails form_for在Ruby on Rails中的工作原理

Ruby on rails form_for在Ruby on Rails中的工作原理,ruby-on-rails,rails-activerecord,params,form-for,form-helpers,Ruby On Rails,Rails Activerecord,Params,Form For,Form Helpers,我是个新手。我已经阅读了API文档。但仍然不明白form_for是如何工作的 首先,在Ruby on Rails教程中,表单为follow按钮: <%= form_for(current_user.relationships.build(followed_id: @user.id)) do |f| %> <div><%= f.hidden_field :followed_id %></div> <%= f.submit "Follow

我是个新手。我已经阅读了API文档。但仍然不明白form_for是如何工作的

首先,在Ruby on Rails教程中,表单为follow按钮:

<%= 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 %>

我理解
当前的\u user.relationships.build(后面的\u id:@user.id)
意味着一个新记录。但为什么我们不能只提交并触发控制器来保存记录而不隐藏字段?为什么我们仍然需要将id发布到控制器

其次,在隐藏字段中,
:followed\u id
是什么意思?我认为这是一个符号,即它只等于“followerd_id”,而不是id的变量。如果这只是输入字段的名称,那么它的值是多少

第三,
form_for
如何知道提交内容应该发送到哪里?
表单\u将发布到哪个控制器和操作

第四,
params
如何与
form_一起工作?在这个follow按钮的情况下,
params[:relationship][:followed\u id]
将在控制器中返回
@user.id
。它如何知道第一个散列属性是
:relationship
?我们既没有提到关系的形式,也没有提到@relationship的形式


我知道这些问题可能很愚蠢,但我真的被卡住了。任何帮助都将不胜感激

我没有做那个教程,所以如果我没有直接回答你的问题,请注意

看一看,它详细地解释了你的问题,可能比我更清楚

form\u for(path/to/your/controller/action)
是一种帮助方法,用于创建带有POST或GET请求url路径的HTML表单元素。助手根据您在控制器操作中要求执行的操作,知道它应该是新记录还是更新记录

比如说 在控制器中

def new
  @my_instance_variable = Myobject.new
end
在您的视图中new.html.erb

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

在阅读了《Rails 4 Way》一书后,我现在对form_有了更好的理解

11.9.1.5显示现有值。 如果您正在编辑Person的现有实例,则该对象的属性值将填充到 表格

这样,当我们使用
当前的\u user.relationships.build(后跟的\u id:@user.id)
构建关系时,将创建关系实例并获得属性
后跟的\u id
。因此,我们实际上是通过表单编辑关系,而不是“创建”关系

然后Rails将知道您正在编辑并将现有属性“followed_id”加载到字段中。因此,我们不需要像使用
f那样为字段赋值。hidden\u field:followind\u id,value:@user.id

我们必须使用字段将id传递给参数的原因是HTTP服务器是无状态的,它不记得您正在与哪个用户创建关系

为当前用户.relationships.build(跟随用户id:@user.id)
而不是为@relationship编写
表单的优点之一是,我们不需要在控制器中像这样编写“if条件”:

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
参数将被发送到属于实例模型的控制器。“发布”方法将用于创建操作,“删除”方法将用于销毁,“补丁”方法将用于更新,等等

参数将是一个散列,其中包含另一个散列,如{instace_name:{field_1:value1,field_2:value2}}或完整参数,如下所示

   Parameters: {"utf8"=>"✓",
     "authenticity_token"=>"afl+6u3J/2meoHtve69q+tD9gPc3/QUsHCqPh85Z4WU=",
     "person"=>{"first_name"=>"William", "last_name"=>"Smith"},
     "commit"=>"Create"}

非常感谢你。这是一个很好的答案。但我还是很困惑。首先,如果“form_for”后面的输入是path。那么Myobject.new和Myobject.build的表单_应该指导我们执行“新建”和“构建”操作吗?但相反,它引导我采取行动“创造”。不管怎样,只要我知道它现在如何将我重定向到正确的控制器,这不是什么大问题。在当前用户的
表单\u.relationships.build(后面的\u id:@user.id)
,当前用户的
表单\u.relationships.build只需要第一部分
即可。这意味着最后一部分
(后面的\u id:@user.id)
不是必需的,对吗?或者它是否扮演一些角色来帮助隐藏字段值?我想我还是没有得到第一个和第二个问题的答案。也许我应该花更多的时间阅读你首先建议的Rails指南。谢谢,您需要用适当的信息告诉rails您想要构建什么,所以是的,您需要最后一部分。当存在模型关联时,将使用构建方法。您可以查看[api]()。如果不添加@user.id,则后面的\u id将导致nil。是的,它们最终导致创建操作,这正是您想要的;).build方法已经用信息构建了对象,您只需要保存它,这就是创建操作的目的。新的操作只是一个页面,您可以在其中创建一个表单,让用户编写信息,然后在提交时,它将重定向到创建操作并保存,除非验证失败。
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
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
   Parameters: {"utf8"=>"✓",
     "authenticity_token"=>"afl+6u3J/2meoHtve69q+tD9gPc3/QUsHCqPh85Z4WU=",
     "person"=>{"first_name"=>"William", "last_name"=>"Smith"},
     "commit"=>"Create"}