Ruby on Rails: Are “form_for(:product, …)” and “form_for(@product, …)” equivalent?

前端 未结 3 508
囚心锁ツ
囚心锁ツ 2021-02-06 13:09

Is

<%= form_for(:product, :url => {:action => \'update\', :id => @product.id})) do |f| %>
  ...
<% end %>

and

<         


        
相关标签:
3条回答
  • 2021-02-06 13:20

    That's quite a long form_for you've got there. The short answer to your question: @product is useful for determining what action to go to for a resource that can have many objects, which is what this sounds like. :product on the other hand will always go to the same action, update. This is best used for singular resources. A great explanation of the resources can be found in the Routing Guide. It's also explained in the Getting Started guide.

    Your second form_for could be shorted right down to this:

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

    All is explained in the Routing and Getting Started guides.

    Also, I saw in your profile you're from Melbourne. There's the Ruby on Rails Oceania Google group which lists the meetups around the country. There's one each month in Melbourne which you may want to attend to meet like minded people.

    0 讨论(0)
  • 2021-02-06 13:23

    The @product in the form_for helper ships with more features.

    The :product only affects the input field's id and name. For example you have a text filed in the form:

    <%= form_for :product, :url => {...} do |f| %>
      <%= f.text_field :price %>
    <% end %>
    

    The generated html would look like:

    <input type="text" id="product_price" name="product[price]" />
    

    The id and name value is determined by the :product.to_s and the text field name.

    While if you use @product, the :url is not necessary because the url would be determined according to the @product's status:

    • if the @product is a new record, the url would post to create
    • otherwise, the url would post to update

    And the input filed's id and name is affected by @product's class name, so it's important when you're using single table inheritant. The input filed's value is automatically assigned with the @product's attribute value. So if you use @product, the html output would look like:

    <input type="text" id="product_price" name="product[price]" value="some value" />
    

    Assume the @product's class name is Item, then the output would change to:

    <input type="text" id="item_price" name="item[price]" value="some value" />
    

    And of course you can use both of :product and @product:

    <%= form_for :product, @product do |f| %>
    

    The :product controls input filed's name and id, and the @product controls the url and input field's value.

    0 讨论(0)
  • 2021-02-06 13:35

    Similar, but not the same. When you use @product you have the benefit of being able to automatically populate values to the form fields from the model instance.

    For example, if you in the action :new in your Controller assign @product like this:

    @product = Product.new
    

    Then there will probably not be any difference in the generated form. However, if you follow this up in you :create action like this:

    @product = Product.new(params[:product])
    if @product.save
      ...
    else
      render :action => :new
    end
    

    Then if it is unable to save the @product instance, then it will render the same form as in :new but this time have all the fields populated with the values posted. That would not have been possible if you used :product

    0 讨论(0)
提交回复
热议问题