Reputation: 222
I just learn RoR and confuse now how to insert data to db. Here's my code:
book_insert.html.erb
<%= content_for :helloworld do %>
<%= form_tag("/insert", method: "post") do %>
<%= label_tag(:title, "Title") %>
<%= text_field_tag(:title) %><br>
<%= label_tag(:price, "Price") %>
<%= number_field_tag(:price) %><br>
<%= label_tag(:subject_id, "Subject ID") %>
<%= number_field_tag(:subject_id) %><br>
<%= label_tag(:description, "Description") %>
<%= text_field_tag(:description) %><br>
<br>
<%= submit_tag("Submit") %>
<% end %>
<% end %>
book_controller.rb
class BookController < ApplicationController
def insert
@book = Book.new(book_params)
@book.save
render :book_page
end
def book_params
params.require(:books).permit(:title, :price, :subject_id, :description)
end
def showinsert
render :book_insert
end
end
It returns error:
Completed 400 Bad Request in 4ms (ActiveRecord: 0.0ms) ActionController::ParameterMissing (param is missing or the value is empty: books):
Please help. Thanks
Upvotes: 0
Views: 282
Reputation: 33542
form_tag
normally used to submit non-model actions to the mapped controller#action
. You probably need to use form_for
and its corresponding helpers inside the form
<%= content_for :helloworld do %>
<%= form_for Book.new, url: "/insert", method: "post" do |f| %>
<%= f.label :title %>
<%= f.text_field :title %><br>
<%= f.label :price %>
<%= f.number_field :price %><br>
<%= f.label :subject_id %>
<%= f.number_field :subject_id %><br>
<%= f.label :description %>
<%= f.text_field :description %><br>
<br>
<%= f.submit "Submit" %>
<% end %>
<% end %>
With the above code, the params
would be passed inside :book => {}
hash, so you need to change the book_params
to below
def book_params
params.require(:book).permit(:title, :price, :subject_id, :description)
end #^
Upvotes: 2
Reputation: 101891
The params.require
method requires that the key books
is present in the hash - if not it raises an ActionController::ParameterMissing
exception.
To nest inputs you need to name them accordingly:
<%= form_tag("/insert", method: "post") do %>
<%= label_tag("Title") %>
<%= text_field_tag("books[title]") %><br>
<%= label_tag("Price") %>
<%= number_field_tag("books[price]") %
...
<%= submit_tag("Submit") %>
<% end %>
This will give the params hash:
{ books: { title: 'Life & Times of Michael K', price: 99 } }
However thats pretty tedious. A better way is to use the forms helpers and setup your routes and controller according to the conventions:
# config/routes.rb
resources :books
# app/views/books/new.html.erb
<%= form_for(@book) do |f| %>
<div class="field">
<%= f.label :title %>
<%= f.text_field :title %>
</div>
# ...
<%= f.submit %>
<% end %>
# app/controllers/books_controller.rb
class BooksController < ApplicationController
# this renders the form to create a new book
# GET /books/new
def new
@book = Book.new
end
# In Rails its called create - not insert
# POST /books
def create
@book = Book.new(book_params)
if @book.save
redirect_to @book
else
render :new
end
end
# This is the path to show a book
# its also where we redirect after creating the book
# GET /books/:id
def show
@book = Book.find(params[:id])
end
# ...
private
def book_params
# note thats its book singular - not plural
params.require(:book).permit(:title, :price, :subject_id, :description)
end
end
Upvotes: 2
Reputation: 2398
You should do book
in the book_params
method instead of books
:
def book_params
params.require(:book).permit(:title, :price, :subject_id, :description)
end
Upvotes: -1