user5527042
user5527042

Reputation:

form_for Ruby On Rails

I'm trying to follow a tutorial on using basic AJAX to add a record to a list in place, and I'm having issues using form form_for.

Here is my code.

<%= form_for ([@product, @product.new]) do |p| %>

    <p>
    <%= p.label :product_part %>
    <%= p.text_field :product_part%>
    </p>

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

The error I am getting is

undefined method `new' for nil:NilClass

I understand why I am getting the error (@products hasn't been "initialized") but I have no idea how to fix this issue (I am sure it's simple). I have seen something about putting a resource in the routes file, but I do not know for sure.

Upvotes: 0

Views: 64

Answers (3)

Gupta
Gupta

Reputation: 10358

I would say In case you need to look the form_for helper ; to understand the behavior of the method.

The method form_for It accept the argument as record, options = {}. The value of record could be a symbol object or a newly object of respective class in your case Person.new. Second argument could be :url, :namespace, :method, :authenticity_token, :remote , :enforce_utf8, :html

Among them :remote => true option is used as the Ajaxify your request.

form_for is a helper that assists with writing forms. form_for takes a :remote option. It works like this:

<%= form_for(@article, remote: true) do |f| %>
  ....
<% end %>

This will generate the following HTML:

 <form accept-charset="UTF-8" action="/articles" class="new_article" data-remote="true" id="new_article" method="post">
  ...
 </form>

Note the data-remote="true". Now, the form will be submitted by Ajax rather than by the browser's normal submit mechanism.

For more info about Form-For helper

Hope this solve your problem!!!.

Upvotes: 0

Richard Peck
Richard Peck

Reputation: 76774

Do this:

#app/controllers/products_controller.rb
class ProductsController < ApplicationController
   def new
      @product = Product.new
      render :form
   end

   def edit
      @product = Product.find params[:id]
      render :form
   end
end

#app/views/products/form.html.erb
<%= form_for @product, remote: true do |f| %>
   <%= p.label :product_part %>
   <%= p.text_field :product_part%>
   <%= f.submit %>
<% end %>

This will do everything you need for both the new and edit methods (which you raised concerns about in your comments with @meagar).

This should be corroborated with the following routes (you can see why here):

#config/routes.rb
resources :products

Upvotes: 0

user229044
user229044

Reputation: 239230

If you're trying to make a form for a new product, you should (in your controller) be setting @product to an instance of a new Product:

# app/controllers/products_controller.rb
def new
  @product = Product.new
end

In your view, using [@product, @product.new] makes no sense. You can't invoke new on an instance of a product. It's very unclear why you're not simply using the following, which is the correct use of form_for with a new instance of an ActiveRecord model:

form_for @product do |p|

Upvotes: 2

Related Questions