错误:表单中有很多关系,更新时有重复数据(Error: has-many relationship in form, duplicate data when update)
我正在做电子商务。 我的产品有很多产品选择,同时它们只有一个变体。 我尝试使视图创建产品可以选择添加块,其中显示模型的字段以及与之关联的变体的更改。 问题是,例如,当我创建一个包含5个选项的产品时,当我将它更新为10时,如果我再次更新它,则会有20个选项。我找不到问题,他们为什么重复。 我留下下面的代码。
产品架构,选项产品和变体
create_table "options_products", force: :cascade do |t| t.integer "product_id" t.float "price" t.integer "stock" t.datetime "created_at", null: false t.datetime "updated_at", null: false end create_table "products", force: :cascade do |t| t.string "name", default: "", null: false t.text "description" t.integer "category_id" t.integer "vendor_id" t.string "state", null: false t.boolean "shippingInside", null: false t.datetime "created_at" t.datetime "updated_at" t.integer "priceComparison" t.string "image1_file_name" t.string "image1_content_type" t.integer "image1_file_size" t.datetime "image1_updated_at" t.float "price" end create_table "variants", force: :cascade do |t| t.string "tipoVariant" t.integer "options_product_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.boolean "controlStock" t.string "image_file_name" t.string "image_content_type" t.integer "image_file_size" t.datetime "image_updated_at" end
用于添加和删除字段的脚本
$(document).on 'ready page:load', -> $('form').on 'click', '.remove_field', (event) -> $(this).prev('input[type=hidden]').val('1') $(this).closest('fieldset').hide() event.preventDefault() $('form').on 'click', '.add_field', (event) -> time = new Date().getTime() regular_expression = new RegExp($(this).data('id'), 'g') $(this).before($(this).data('fields').replace(regular_expression,time)) event.preventDefault()
产品创建和更新
def create @product = Product.new(product_params) respond_to do |format| if @product.save format.html { redirect_to @product} format.json { render :show, status: :created, location: @product } else format.html { render :new } format.json { render json: @product.errors, status: :unprocessable_entity } end end end def update respond_to do |format| if @product.update(product_params) format.html { redirect_to @product} format.json { render :show, status: :ok, location: @product } else format.html { render :edit } format.json { render json: @product.errors, status: :unprocessable_entity } end end end
产品参数
def product_params params.require(:product).permit(:name, :description, :state, :shippingInside, :vendor_id, :category_id, :priceComparison, :image1, :price, offer_attributes: [:status], options_products_attributes: [:price, :stock, variant_attributes: [:tipoVariant, :controlStock, :image]])
在应用助手中添加关联功能
def link_to_add_association(name, field, association) new_object = field.object.send(association).klass.new new_object_id = new_object.object_id fields = field.fields_for(association, new_object, child_index: new_object_id) do |builder| new_object.build_variant render(association.to_s.singularize + '_field', f: builder) end link_to(name, '#', class: 'add_field', data: { id: new_object_id, fields: fields.gsub("\n", "") }) end
产品型号
class Product < ActiveRecord::Base #relations belongs_to :category belongs_to :vendor has_one :offer, :dependent => :destroy has_many :options_products, :dependent => :destroy #accepts accepts_nested_attributes_for :offer, allow_destroy: true accepts_nested_attributes_for :options_products, allow_destroy: true #validations validates :name, presence:true validates :name, uniqueness:true validates :state, presence:true validates :category_id, presence:true validates :vendor_id, presence:true has_attached_file :image1, styles: {medium: "300x300>", thumb: "150x150#" } validates_attachment_content_type :image1, content_type: /\Aimage\/.*\z/ end
期权产品模型
class OptionsProduct < ActiveRecord::Base belongs_to :product has_one :variant, :dependent => :destroy accepts_nested_attributes_for :variant, allow_destroy: true end
变体模型
class Variant < ActiveRecord::Base belongs_to :options_product has_attached_file :image, styles: {medium: "300x300>", thumb: "150x150#" } validates_attachment_content_type :image, content_type: /\Aimage\/.*\z/ end
产品的形式
= form_for @product, html: { multipart: true } do |f| .row .form-group.col-lg-6 .field = f.file_field :image1 .row .form-group.col-lg-6 .field = f.text_field :name, :placeholder => 'Nombre', :class => 'form-control input-border-left' .row .form-group.col-lg-6 .field = f.text_area :description, :placeholder => 'Descripcion', :class => 'form-control input-border-left' .row .form-group.col-lg-6 .field = f.number_field :price, :placeholder => 'Precio a mostrar', :class => 'form-control input-border-left' .row .form-group.col-lg-6 .field = f.label :Estado %br/ = f.select :state, options_for_select(['Disponible', 'No disponible']) .row .form-group.col-lg-6 .field = f.label :Envio %br/ = f.check_box :shippingInside .row .form-group.col-lg-6 .field = f.text_field :priceComparison, :placeholder => 'Precio anterior', :class => 'form-control input-border-left' .row .form-group.col-lg-6 .field = f.label :vendor_id %br/ = f.select :vendor_id, Vendor.all.collect { |vendor| [vendor.name, vendor.id] } .row .form-group.col-lg-6 .field = f.label :category_id %br/ = f.select :category_id, Category.all.collect { |category| [category.name, category.id] } = f.fields_for :offer, @product.build_offer do |o| = o.label :Oferta %br/ = o.check_box :status %br/ .row = f.fields_for :options_products do |op| = render 'options_product_field', f: op = link_to_add_association 'Agregar variante', f, :options_products %br/ .actions = f.submit "Enviar", :class => 'button btn btn-primary bold'
options_product_field文件
%fieldset .row .form-group.col-lg-6 .field = f.text_field :price, :placeholder => 'Precio', :class => 'form-control input-border-left' .row .form-group.col-lg-6 .field = f.text_field :stock, :placeholder => 'Stock', :class => 'form-control input-border-left' = f.fields_for :variant do |v| .row .form-group.col-lg-6 .field = v.text_field :tipoVariant, :placeholder => 'Tipo de variante', :class => 'form-control input-border-left' .row .form-group.col-lg-6 .field = v.label :ControlarStock %br/ = v.check_box :controlStock .row .form-group.col-lg-6 .field = v.label :ImagenDeVariante %br/ = v.file_field :image = f.hidden_field :_destroy = link_to 'Remover variante', '#', class: 'remove_field'
I am doing an e-commerce. I have products which have many options of products and at the same time they only have one variant. I try to make the view to create the product have the option of add a block where appears the fields of the model and the changes of the variant which is associated to it. The problem is, for example, when i create a product with 5 options, when i update it increases to 10, and if i update it again, there will be 20. I can't find the problem why they are duplicating. I leave the codes below.
Schema of Product, option-product and variant
create_table "options_products", force: :cascade do |t| t.integer "product_id" t.float "price" t.integer "stock" t.datetime "created_at", null: false t.datetime "updated_at", null: false end create_table "products", force: :cascade do |t| t.string "name", default: "", null: false t.text "description" t.integer "category_id" t.integer "vendor_id" t.string "state", null: false t.boolean "shippingInside", null: false t.datetime "created_at" t.datetime "updated_at" t.integer "priceComparison" t.string "image1_file_name" t.string "image1_content_type" t.integer "image1_file_size" t.datetime "image1_updated_at" t.float "price" end create_table "variants", force: :cascade do |t| t.string "tipoVariant" t.integer "options_product_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.boolean "controlStock" t.string "image_file_name" t.string "image_content_type" t.integer "image_file_size" t.datetime "image_updated_at" end
Script for add and remove fields
$(document).on 'ready page:load', -> $('form').on 'click', '.remove_field', (event) -> $(this).prev('input[type=hidden]').val('1') $(this).closest('fieldset').hide() event.preventDefault() $('form').on 'click', '.add_field', (event) -> time = new Date().getTime() regular_expression = new RegExp($(this).data('id'), 'g') $(this).before($(this).data('fields').replace(regular_expression,time)) event.preventDefault()
Product create and update
def create @product = Product.new(product_params) respond_to do |format| if @product.save format.html { redirect_to @product} format.json { render :show, status: :created, location: @product } else format.html { render :new } format.json { render json: @product.errors, status: :unprocessable_entity } end end end def update respond_to do |format| if @product.update(product_params) format.html { redirect_to @product} format.json { render :show, status: :ok, location: @product } else format.html { render :edit } format.json { render json: @product.errors, status: :unprocessable_entity } end end end
Product Params
def product_params params.require(:product).permit(:name, :description, :state, :shippingInside, :vendor_id, :category_id, :priceComparison, :image1, :price, offer_attributes: [:status], options_products_attributes: [:price, :stock, variant_attributes: [:tipoVariant, :controlStock, :image]])
function in application helper to add association
def link_to_add_association(name, field, association) new_object = field.object.send(association).klass.new new_object_id = new_object.object_id fields = field.fields_for(association, new_object, child_index: new_object_id) do |builder| new_object.build_variant render(association.to_s.singularize + '_field', f: builder) end link_to(name, '#', class: 'add_field', data: { id: new_object_id, fields: fields.gsub("\n", "") }) end
Product model
class Product < ActiveRecord::Base #relations belongs_to :category belongs_to :vendor has_one :offer, :dependent => :destroy has_many :options_products, :dependent => :destroy #accepts accepts_nested_attributes_for :offer, allow_destroy: true accepts_nested_attributes_for :options_products, allow_destroy: true #validations validates :name, presence:true validates :name, uniqueness:true validates :state, presence:true validates :category_id, presence:true validates :vendor_id, presence:true has_attached_file :image1, styles: {medium: "300x300>", thumb: "150x150#" } validates_attachment_content_type :image1, content_type: /\Aimage\/.*\z/ end
Option Product Model
class OptionsProduct < ActiveRecord::Base belongs_to :product has_one :variant, :dependent => :destroy accepts_nested_attributes_for :variant, allow_destroy: true end
Variant model
class Variant < ActiveRecord::Base belongs_to :options_product has_attached_file :image, styles: {medium: "300x300>", thumb: "150x150#" } validates_attachment_content_type :image, content_type: /\Aimage\/.*\z/ end
_form of Product
= form_for @product, html: { multipart: true } do |f| .row .form-group.col-lg-6 .field = f.file_field :image1 .row .form-group.col-lg-6 .field = f.text_field :name, :placeholder => 'Nombre', :class => 'form-control input-border-left' .row .form-group.col-lg-6 .field = f.text_area :description, :placeholder => 'Descripcion', :class => 'form-control input-border-left' .row .form-group.col-lg-6 .field = f.number_field :price, :placeholder => 'Precio a mostrar', :class => 'form-control input-border-left' .row .form-group.col-lg-6 .field = f.label :Estado %br/ = f.select :state, options_for_select(['Disponible', 'No disponible']) .row .form-group.col-lg-6 .field = f.label :Envio %br/ = f.check_box :shippingInside .row .form-group.col-lg-6 .field = f.text_field :priceComparison, :placeholder => 'Precio anterior', :class => 'form-control input-border-left' .row .form-group.col-lg-6 .field = f.label :vendor_id %br/ = f.select :vendor_id, Vendor.all.collect { |vendor| [vendor.name, vendor.id] } .row .form-group.col-lg-6 .field = f.label :category_id %br/ = f.select :category_id, Category.all.collect { |category| [category.name, category.id] } = f.fields_for :offer, @product.build_offer do |o| = o.label :Oferta %br/ = o.check_box :status %br/ .row = f.fields_for :options_products do |op| = render 'options_product_field', f: op = link_to_add_association 'Agregar variante', f, :options_products %br/ .actions = f.submit "Enviar", :class => 'button btn btn-primary bold'
options_product_field file
%fieldset .row .form-group.col-lg-6 .field = f.text_field :price, :placeholder => 'Precio', :class => 'form-control input-border-left' .row .form-group.col-lg-6 .field = f.text_field :stock, :placeholder => 'Stock', :class => 'form-control input-border-left' = f.fields_for :variant do |v| .row .form-group.col-lg-6 .field = v.text_field :tipoVariant, :placeholder => 'Tipo de variante', :class => 'form-control input-border-left' .row .form-group.col-lg-6 .field = v.label :ControlarStock %br/ = v.check_box :controlStock .row .form-group.col-lg-6 .field = v.label :ImagenDeVariante %br/ = v.file_field :image = f.hidden_field :_destroy = link_to 'Remover variante', '#', class: 'remove_field'
原文:https://stackoverflow.com/questions/39552566
最满意答案
程序看起来不错我猜你错过了分隔符
delimiter // CREATE PROCEDURE dowhile() BEGIN DECLARE v1 INT DEFAULT 5; WHILE v1 > 0 DO SET v1 = v1 - 1; END WHILE; END; // delimiter ;
The procedure looks ok I guess you are missing the delimiter
delimiter // CREATE PROCEDURE dowhile() BEGIN DECLARE v1 INT DEFAULT 5; WHILE v1 > 0 DO SET v1 = v1 - 1; END WHILE; END; // delimiter ;
相关问答
更多-
这个mySQL create table语句中的语法错误是什么?(What is my syntax error in this mySQL create table statement?)[2024-02-21]
更改: `tag` ENUM(‘red’,’orange’,’yellow’,’green’,’blue’,’violet’,’brown’,’black’) 至: `tag` ENUM('red', 'orange','yellow','green','blue','violet','brown','black') Change: `tag` ENUM(‘red’,’orange’,’yellow’,’green’,’blue’,’violet’,’brown’,’black’) To: `t ... -
sql语句中的语法错误?(Syntax error in sql statement?)[2022-08-12]
问题是order是mysql的保留关键字; 所以你有两个解决方案可供你使用1:如果你需要一些技巧来使用这项工作,万一你的情况下使用反引号逃脱`order` 2:您可以使用复数作为表名称,如订单 ps = con.prepareStatement("INSERT INTO `order`(status,ordered_on,total_price,user_id) " + " VALUES(?,?,?,?)"); ps.setString(1,"pending"); ... -
PASSWORD这个词是一个保留关键字。 要使用它,你应该把方括号中的字符串括起来 OleDbCommand cmd = new OleDbCommand("Insert into Info (username, [password]) Values ('" + username + "', '" + password + "')", conn); 请,请不要使用字符串连接来构建sql语句。 这是一个非常糟糕的做法,导致其他语法错误(用单引号的用户名或密码)或最糟糕的SQL注入攻击。 看看这里 ,如果你有 ...
-
你不需要--database = mysql -h "$host" --user="$user" --password="$pass" "$db" -e "UPDATE student SET balance=balance-$deduct WHERE pid=$pid"; 您也可以在查询中Use $db You don't need --database= mysql -h "$host" --user="$user" --password="$pass" "$db" -e "UPDATE studen ...
-
带有TIME数据类型的MySQL INSERT语句中的语法错误(Syntax error in MySQL INSERT statement with TIME datatypes)[2021-09-15]
您必须为所有列指定一些内容 。 INSERT INTO `lwljhb_lwl_matches` (id, ...) VALUES (NULL, ...) You must specify something for all columns. INSERT INTO `lwljhb_lwl_matches` (id, ...) VALUES (NULL, ...) -
程序看起来不错我猜你错过了分隔符 delimiter // CREATE PROCEDURE dowhile() BEGIN DECLARE v1 INT DEFAULT 5; WHILE v1 > 0 DO SET v1 = v1 - 1; END WHILE; END; // delimiter ; The procedure looks ok I guess you are missing the delimiter delimiter // CREATE PRO ...
-
mysql语法错误(mysql syntax error)[2023-12-23]
您需要从firstName和lastName周围删除引号: INSERT INTO merchants (firstName,lastName) VALUES ('Bob','Smith') 列名称是标识符,因此不会引用。 编辑: 可以使用反引号(`)引用列名,但只有在列名包含与MySQL关键字匹配的特殊字符或列名时才需要。 You need to remove the quotes from around firstName and lastName: INSERT INTO merchants ... -
找到了。 它是phpMyAdmin中的一个字段,默认情况下设置为分号(;)。 我已将其更改为未使用的char并且查询正常运行。 Found it. It was a field in phpMyAdmin which is set to semicolon(;) by default. I have changed it to an unused char and the query ran normally.
-
具有哈希列名称的CREATE TABLE语句中的MySQL语法错误(MySQL syntax error in CREATE TABLE statement with hash column names)[2023-10-21]
您所观察到的似乎是一个错误。 摘自文档 : 标识符可以以数字开头,但除非引用可能不仅仅由数字组成。 混淆似乎是由于“6e87”是有效数字的事实,即使它不完全由数字组成。 这是指数表示法。 出于某种原因,虽然不带引号的标识符可以以数字开头,但它不能以指数表示法的数字开头。 通过使用反引号或双引号引用标识符,这很容易修复。 编辑: 您可以使用以下两个简单查询来复制问题: select 6 as 5_1 select 6 as 5e1 select 6 as 5f1 select 6 as 5e1f 第一 ... -
在MySQL中使用嵌套的IF语句没有任何问题。 我认为问题是你试图增加变量的方式: SET daysEntitled += 1.00; ^^ not allowed 请改用此代码: IF dayOfMonth <= 15 THEN SET daysEntitled = daysEntitled + 1.00; ENDIF; There is nothing wrong with having a nested IF statement in MySQL. I th ...