我正在创建产品数据库,并希望检查何时创建了新产品(如果该产品已经存在)。
99%的情况下,产品应该具有唯一的产品代码,但是有时当修订版本带有相同的产品代码时,情况并非如此。
我想拥有它,以便数据库检查产品代码是否已经存在。如果是这样,则用户可以继续创建产品,转到已经存在的产品,或者取消。
我正在尝试在控制器中实现此功能,但似乎无法获取存在的语法?方法正确。有人可以指出我要去哪里了吗?
def create
@product = Product.new(product_params)
if Product.product_code.exists?(@product.product_code)
render 'new'
flash[:error] = "This product already exists."
elsif @product.save
redirect_to @product
else
render 'new'
end
end
答案 0 :(得分:0)
您应该注意,您在控制器中执行的操作或向模型添加标准唯一性验证将根本不允许创建重复的产品。
这只会继续将用户发送回表单:
def create
@product = Product.new(product_params)
if Product.exists?(product_code: @product.product_code)
render 'new'
flash[:error] = "This product already exists."
elsif @product.save
redirect_to @product
else
render 'new'
end
end
如果只想警告用户一次,则可以在模型上附加virtual attribute并将其用作验证的条件:
class Product < ApplicationRecord
attribute :dup_warning, :boolean, default: true
validate :lax_product_code_uniquenes
def lax_product_code_uniqueness
if new_record? && !dup_warning && Product.exists(product_code: self.product_code)
errors.add(:product_code, 'is not unique - are you sure?')
self.dup_warning = true
end
end
end
然后将虚拟属性添加到表单:
<%= form_with(model: @product) do |f| %>
...
<%= f.hidden_input(:dup_warning) %>
...
<% end %>
除了将dup_warning
添加到参数白名单之外,您不需要在控制器中做任何事情。
def create
@product = Product.new(product_params)
if @product.save
redirect_to @product
else
render 'new'
end
end
def product_params
params.require(:product)
.permit(:foo, :bar, :product_code, :dup_warning)
end
答案 1 :(得分:-1)
您可能应该使用if Product.product_code.exists?(@product.product_code)
代替if @product.product_code.present?
UPD:谢谢大家,在下面评论。
正确使用exists?
是Product.where(product_code: @product.product_code).exists?