新手问题 看 Rails Guides 的新手问题 :posts_path 与 create 动作的对应

bigpig85 · September 29, 2013 · Last by pokrpokr replied at February 04, 2016 · 5961 hits

新手问题,在看 RoR guides,在访问 localhost:3000/posts/new 的时候,如果点击提交后会转到 create 动作,我想知道这个点击后转到 create 动作是在哪里写的?是 form_for 后面的 :post 来定义的吗?这个跟 create 动作是怎么关联的呢?

In this example, the posts_path helper is passed to the :url option. What Rails will do with this is that it will point the form to the create action of the current controller, the PostsController, and will send a POST request to that route

<%= form_for :post, url: posts_path do |f| %>
  <p>
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </p>

  <p>
    <%= f.label :text %><br>
    <%= f.text_area :text %>
  </p>

  <p>
    <%= f.submit %>
  </p>
<% end %>

rake routes 的输出:

   Prefix Verb   URI Pattern               Controller#Action
    posts GET    /posts(.:format)          posts#index
          POST   /posts(.:format)          posts#create
 new_post GET    /posts/new(.:format)      posts#new
edit_post GET    /posts/:id/edit(.:format) posts#edit
     post GET    /posts/:id(.:format)      posts#show
          PATCH  /posts/:id(.:format)      posts#update
          PUT    /posts/:id(.:format)      posts#update
          DELETE /posts/:id(.:format)      posts#destroy
     root GET    /                         welcome#index

posts_controller 裡面寫啊

是由form_for来确定的,form_for :post 会默认生成向/posts提交的表单,而POST /posts这个 route 对应的就是posts#create方法。form_for :post, url: posts_path则是使用url参数指定了提交表单的地址为posts_path,你也可以指定其它的地址。

routes.rb 里面 resource 默认带了的

#2 楼 @edgar_wang_cn 多谢回复,那这里 form_for 后面的:post 和 route 中的 POST /posts 是怎么对应的呢?

#2 楼 @edgar_wang_cn 是可以在 form_for 后面跟要使用的方法吧,比如默认是指向:post 的,就是会指向/POST,如果我在后面加上 method: :post 跟不加的效果一样,如果加上:patch 就是指向了 PATCH,也就是 update 方法,如果加上:delete,就是指向了 DELETE 也就是控制器中的 destroy 方法了对吧

<%= form_for :post, url: posts_path, method: :post do |f| %>

#5 楼 @bigpig85 基本上是对的。不过在你使用符号形式(即form_for :post)时,你要注意methodurl的对应关系,比如POST /posts对应create方法,而PATCH /posts/:id对应于update方法,updatedestroy之类的方法需要指定对象来操作。你可以自己改动几次看看具体效果。推荐你去看看这个 http://guides.rubyonrails.org/form_helpers.html

#6 楼 @edgar_wang_cn 是的,今天试了,对于 update 和 destroy 方法需要指定对象

<%= form_for :post, url: post_path(@post.id), method: :patch do |f| %>

感谢指点~

#7 楼 @bigpig85 直接使用<%= form_for @post do |f| %>这种形式也可以。

#8 楼 @edgar_wang_cn 是呀,后面我看到用了 partials 后,在_form.html.erb 中就是这么写的,这么又怎么理解呢?

#9 楼 @bigpig85 它跟form_for :post这种形式是类似的,不过form_for可以通过判断实例对象@post是否已存在于数据库中来确定urlmethod,所有就不需要特别指定urlmethod了。

#6 楼 @edgar_wang_cn 请问我不用那 7 条资源路由,要让这个表单提交时走自己创建的路由,我该怎么设置路由,<%= form_for :post, url: membersadd do |f| %> ,membersadd 这个路由我要怎么设置

@yty 你可以用

post 'membersadd' => 'members#create'

这种写法,后面的members#create要根据你的 controller 自行设定,然后就可以把 url 设为membersadd_path了。

#12 楼 @edgar_wang_cn 我想问下,我也是卡在这里了,post_path 不是对应 get 和 post 么,那么为什么是自动默认为是用 post 方法呢,如果可以手动设置,是按照上边说的,加上 method::get 这样使用 get 方法?

#13 楼 @pokrpokr posts_path 对应的是/posts(.:format)这个 URL,最终这个 form 执行 GET 还是 POST 依赖form_for生成的 form 里的method是 GET 还是 POST。可以用method: :get使生成的表单使用 GET 提交数据。

#14 楼 @edgar_wang_cn 那也就是说一般默认为 post 方法?

#15 楼 @pokrpokr HTML 默认的 form 是 GET,form_for好像默认生成的是 POST 方法的 form。

You need to Sign in before reply, if you don't have an account, please Sign up first.