form_for 如何决定针对特定请求采取什么操作?

How does form_for decide what action is to be taken for a particular request?

我写了下面的代码:-

<%= form_for(:session,url: login_path) do |f| %>

已翻译成

<form action="/login" accept-charset="UTF-8" method="post">  

我的 routes.rb 文件包含以下代码:-

root 'static_pages#home' 
get 'contact'=>'static_pages#contact' 
get 'about'=>'static_pages#about'
get 'help' => 'static_pages#help'
get 'signup' => 'users#new'
get 'login' => 'sessions#new'
post 'login' => 'session#create'
delete 'logout' => 'session#destroy'
resources:users   

我想知道form_for的行动是如何决定的?

如果 @user 不坚持,它会促使您采取 update 行动

如果不坚持 - create

但是你可以自己配置form_for

form_for @user, url: {action: "create"}

在这里,你没有指定实例对象(@model_name),它只是将表单路径分配给你提供的路径:login_path,方法只输出“/login”。

有两条路线

get 'login' => 'sessions#new'
post 'login' => 'session#create'

但是由于 form_for 默认的 HTTP 动词是 post,Rails 将传入的 post 请求与 'login' => 'session#create' 相匹配。

方法 login_path 是在您提供字符串 'login' 时自动定义的,除非您指定其他内容,例如 post 'login' => 'session#create', as: "sign_in",这将执行 sing_in_path

它是 Rails 向后元编程的一部分。

请查看 Rails 表单助手指南,特别是 form_for 的 dealing with model objects. Also, the docs 部分。

关于你的问题,在

  <form action="/login" accept-charset="UTF-8" method="post"> 
        ^^^^^^^^^^^^^^^
           this bit

来自您传递给 form_for 助手的对象的组合

  <%= form_for(:session, url: login_path) do |f| %>
               ^^^^^^^^
                 here

与 url 一起,您(可选)传递给 form_for 帮助程序

  <%= form_for(:session, url: login_path) do |f| %>
                         ^^^^^^^^^^^^^^^
                              here

正如 Joe Half Face 在他的回答中提到的,:session 是一个 symbol,因此 form_for 简单地将 login_path 解析为 action="/login"

如果 :session 是一个实例变量(假设您有一个 Session class 和一个 @session 这样的实例变量),那么您的 form_for 调用可能看起来像这样:

  <%= form_for(@session, url: login_path) do |f| %>

然后 form_for 会根据 @session 对象的状态以不同方式解析 action=(它是新记录吗?已保存的记录?等) .

顺便说一句,form_for 不需要 url 参数。所以,可以这样做:

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

在这种情况下,form_for 使用提供的 @user 对象来推断正确的路径,您会得到

<form action="/users" ... >