简体   繁体   中英

Using partials in Rails

I am following this official guide to learn about Rails, where a blog is built, and I noticed that it doesn't seem to be complete.

On Point 5.13 "Using partials to clean up duplication in views", it recommends to take the form to create a post and to edit it inside a partial, because both are so similar. It does speak about a small difference about the routes that both forms use, but it says it is a problem that will be explained later

Everything except for the form_for declaration remained the same. How form_for can figure out the right action and method attributes when building the form will be explained in just a moment. [...]

But I noticed the guide never actually explains how to do this. (Maybe they just forgot...?)

Can someone explain me how can I solve this problem?

If you follow the Rails conventions, you won't have to do anything. This is well explained in the documentation ( http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for ).

However, further simplification is possible if the record passed to form_for is a resource, ie it corresponds to a set of RESTful routes, eg defined using the resources method in config/routes.rb. In this case Rails will simply infer the appropriate URL from the record itself.

Basically, you need to:

  1. Use form_for helper
  2. Pass model object to it (instead of a symbol)
  3. Have defined resource in routes.rb fi resources :posts

So if you have form_for(@post) , Rails will determine which route to use by checking if @post is a new record.

If you want a complete example, just create a new rails app and create any scaffold:

rails g scaffold User name

You can check that Rails had put a form in a partial: app/views/users/_form.html.erb .

If you want to dig deep, check the source code. The interesting part is in this file .

action, method = object.respond_to?(:persisted?) && object.persisted? ? [:edit, :patch] : [:new, :post]

In our example the @post is assigned to object . Rails is full of such short-cuts, and sometimes the best way of learning about them is looking at the source code. If you know Ruby well, you'll often find source code to be a better explanation that the docs and guides.

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

When @product is a new record, Rails know about it and uses products_path. However when the @product is existed one, Rails uses product_path(@product).

It doesn't do a great job of explaining it. If you look up the page at the two versions of the form, one for new and one for edit you will see they have two different pieces of code after form_for , but they are both passing the @post variable. In the first case, the variable contains a new, empty, Post object.

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

In the edit version it is looking up the record, putting it in the @post variable and passing it to the form.

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

The final version, the partial, does not have the extra code indicating if it's a new action or edit . But due to the URL and the action calling the view, Rails knows which code to sub into the form when using a form partial. More "Rails magic".

<%= form_for @post do |f| %>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM