简体   繁体   中英

Ruby on Rails: Form successfully submitted but no commit into database and no errors displayed

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.

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