尝试创建新行(产品)时,create方法生成的INSERT语句缺少声明为NOT NULL的product_type_id字段。我无法弄清楚为什么Rails不包含insert语句中的product_type_id字段。
尝试保存产品时出现以下错误。
Admin :: ProductsController #create中的ActiveRecord :: StatementInvalid
Mysql2 ::错误:字段'product_type_id'没有默认值:INSERT INTO products
(brand_id
,created_at
,description
,{{1} },image_base
,media_embed
,msrp
,name
,price_override
,thumbnail_desc
,updated_at
,vendor_sku
) VALUES(9,'2014-08-31 16:45:50','','a','b',33.0,'a',3.0,'','2014-08-31 16:45:50 ','',2015)
但是,products表有product_type_id字段:
year
,请求参数显示product_type_id及其值:
desc products
--------------
+-----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| product_type_id | int(11) | NO | MUL | NULL | |
| brand_id | int(11) | YES | MUL | NULL | |
| name | varchar(50) | NO | | NULL | |
| thumbnail_desc | varchar(200) | YES | | NULL | |
| description | text | NO | | NULL | |
| year | int(11) | YES | | NULL | |
| vendor_sku | varchar(30) | YES | MUL | NULL | |
| msrp | decimal(8,2) | YES | | NULL | |
| price_override | decimal(8,2) | YES | | NULL | |
| visible | tinyint(1) | NO | | 1 | |
| available | tinyint(1) | NO | | 1 | |
| image_base | varchar(255) | YES | | NULL | |
| video_source | text | YES | | NULL | |
| media_embed | text | YES | | NULL | |
| deleted_at | datetime | YES | | NULL | |
| created_at | datetime | YES | | NULL | |
| updated_at | datetime | YES | | NULL | |
+-----------------+--------------+------+-----+---------+----------------+
18 rows in set (0.01 sec)
产品型号:
Request
Parameters:
{"utf8"=>"✓",
"authenticity_token"=>"VT42eeLLT/pyQ05ycfU/PeK92LIQ1P7NpWcPDOuOvsg=",
"product"=>{"year"=>"2015",
"brand_id"=>"9",
"name"=>"a",
"description"=>"",
"thumbnail_desc"=>"",
"category_ids"=>["",
"29"],
"product_class_ids"=>[""],
"image_base"=>"a",
"media_embed"=>"b",
"vendor_sku"=>"",
"msrp"=>"33",
"price_override"=>"3",
"visible"=>"1",
"available"=>"1"},
"commit"=>"Create Backpack",
"product_type_id"=>"39"}
ProductType型号:
class Product < ActiveRecord::Base
belongs_to :brand
belongs_to :product_type
has_and_belongs_to_many :categories
has_and_belongs_to_many :product_classes
scope :sorted, lambda { order("name ASC") }
scope :notdeleted, lambda { where(:deleted_at => nil) }
def active
deleted_at.nil?
end
end
:product_type_id符号在产品控制器的params.permit中声明:
class ProductType < ActiveRecord::Base
has_many :product_classes
has_many :products
validates_presence_of :name
scope :sorted, lambda { order("name ASC") }
scope :notdeleted, lambda { where(:deleted_at => nil) }
def active
deleted_at.nil?
end
def active=(val)
self.deleted_at = [nil, '', '0', false].member?(val) ? Time.now : nil
end
end
new.html.erb
class Admin::ProductsController < ApplicationController
layout 'admin'
before_action :confirm_logged_in
before_action :get_product, only: [:edit, :update, :delete, :destroy]
before_action :get_stuff, only: [:new, :create, :edit, :update, :delete, :destroy]
def index
@product_types = ProductType.notdeleted.sorted
end
def show
#redirect_to(:action => 'manage_products')
end
def new
@product_type = ProductType.find(params[:product_type_id])
@product = Product.new({:product_type_id => @product_type.id})
end
def create
@product = Product.new(product_params)
if @product.save
flash[:notice] = 'Product created.'
redirect_to(:action => 'index', :product_type_id => @product_type.id)
else
render("new")
end
end
def edit
end
def update
if @product.update(product_params)
flash[:notice] = 'Product updated.'
redirect_to(:action => 'manage_products', :product_type_id => @product_type.id)
else
render("edit")
end
end
def delete
end
def destroy
@product.update(deleted_at: Time.now, visible: 0, available: 0)
flash[:notice] = "Product deleted."
redirect_to(:action => 'manage_products', :product_type_id => @product_type.id)
end
def manage_products
id = params[:product_type_id]
@product_type = ProductType.find(id)
if params[:include_deleted]
@products = @product_type.products.sorted
else
@products = @product_type.products.notdeleted.sorted
end
#logger.debug("The size of products is #{@products.size}")
end
private
def get_product
@product = Product.find(params[:id])
logger.debug("The product type id is #{@product.product_type_id}")
@product_type = ProductType.find(@product.product_type_id)
logger.debug("The product type is #{@product_type.name}")
logger.debug("The product type has price is #{@product_type.has_price}")
end
def get_stuff
@brands = Brand.sorted
@categories = Category.sorted
end
def product_params
params.require(:product).permit( :product_type_id, :brand_id, :name, :thumbnail_desc, :description, :year, :vendor_sku,
:msrp, :price_override, :visible, :available, :image_base, :media_embed, :active,
:category_ids => [], :product_class_ids => [])
end
end
最后,_form.html.erb
<% @page_title = "Create #{@product_type.name}" %>
<% content_for(:navigation) do -%>
<p><a href="<%= admin_products_path %>"><img src="/assets/layout/icons/arrow_left.png" alt="Back" /> Back to <%= @product_type.name %> List</a></p>
<% end -%>
<%= yield :navigation %>
<%= form_for([:admin, @product], :url => {:action => 'create', :product_type_id => @product_type.id}) do |form| %>
<%= render :partial => 'form', :locals => {:form => form} %>
<div class="form-buttons">
<%= submit_tag("Create #{@product_type.name}") %>
</div>
<% end %>
<%= yield :navigation %>
答案 0 :(得分:0)
我认为你应该像这样重新订购product_type id:
"price_override"=>"3",
"visible"=>"1",
"available"=>"1",
"product_type_id"=>"39"},
"commit"=>"Create Backpack"
答案 1 :(得分:0)
要将缺少的字段放入insert语句,我必须在表单中包含该值并隐藏它:
<% if @product.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@product.errors.count, "error") %> prohibited this page from being saved:</h2>
<%= error_messages_for(@product) %>
</div>
<% end %>
<%= form.hidden_field :product_type_id, :value => @product_type.id %>
<table cellpadding="0" cellspacing="0" class="admintable">
<tr>
<th>Year</th>
<td><%= form.text_field :year, :size => 5 %></td>
</tr>
我还将此行添加到create方法的开头:
@product_type = ProductType.find(params[:product_type_id])
谢谢Alex,让我走上正轨。