I am a RoR newbie and I am currently making a grocery list app. When I tried to submit the form, it renders back to the same page and it doesn't display that I successfully made the grocery list. I checked my database and there's no data which has been commited. At the same time, there's no indication of error both in console or in the browser. Here are my controller, form and the association between a user and a grocery_list.
class GroceryListsController < ApplicationController
def new
@grocery_list = GroceryList.new
end
def create
@grocery_list = current_user.grocery_lists.build(grocery_list_params)
if @grocery_list.save
redirect_to grocery_lists_path, notice: "Created successfully"
else
render :new
end
end
private
def grocery_list_params
params.require(:grocery_list).permit(:name, :date)
end
end
Here's my form
<h1>Make your grocery list</h1>
<%= form_for GroceryList.new do |f| %>
<%= f.text_field :name, placeholder:'Name of your grocery list' %>
<%= f.date_field :date %>
<%= f.submit 'Create list' %>
<% end %>
User model
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :grocery_lists
end
and grocery_list model
class GroceryList < ApplicationRecord
belongs_to :user
belongs_to :product
end
The main issue here is that you have a belongs_to:product
association in your GroceryList
model.
class GroceryList < ApplicationRecord
belongs_to :user
belongs_to :product
end
Since Rails 5 belongs_to
assocations are non-optional by default. This means that the association adds a validates_presence_of:product
association automatically.
Its also most likely not what you want in the first place as it would only let you add a single product to the grocery list. Instead you want a has_many through:
association :
class GroceryList < ApplicationRecord
belongs_to :user
has_many :grocery_list_items
has_many :products, through: :grocery_list_items
end
# rails g model GroceryListItem grocery_list:belongs_to product:belongs_to quantity:decimal
class GroceryListItem < ApplicationRecord
belongs_to :grocery_list
belongs_to :product
end
class Product < ApplicationRecord
has_many :grocery_list_items
has_many :grocery_lists, through: :grocery_list_items
end
You should also pass @grocery_list
to form_for
instead of creating a new instance which will blank out any user input and display the validation errors to the user:
<%= form_for @grocery_list do |f| %>
<% if @grocery_list .errors.any? %>
<div class="errors">
<h2><%= pluralize(@grocery_list.errors.count, "error") %> prohibited this grocery list from being saved:</h2>
<ul>
<% @grocery_list.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.text_field :name, placeholder:'Name of your grocery list' %>
<%= f.date_field :date %>
<%= f.submit 'Create list' %>
<% end %>
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.