这是我的代码。
class Product < ActiveRecord::Base
attr_accessible :name, :price, :released_on
begin
validates :name, uniqueness: true
rescue ActiveRecord::RecordInvalid => e
render( inline: "RESCUED ActiveRecord::RecordInvalid" )
return
end
def self.to_csv(options = {})
CSV.generate(options) do |csv|
csv << column_names
all.each do |product|
csv << product.attributes.values_at(*column_names)
end
end
end
def self.import(file)
CSV.foreach(file.path , headers:true) do |row|
Product.create! row.to_hash # If we want to add a new item
end
end
end
当我保存具有相同名称的重复模型时,会引发异常
ProductsController #import中的ActiveRecord :: RecordInvalid
Validation failed: Name has already been taken
Rails.root: /home/deepender/396-importing-csv-and-excel/store-before
我正在使用救援操作仍然没有处理错误?任何猜错我都错了。
答案 0 :(得分:5)
夫妻俩。您不会将validates
包裹在begin/rescue
块中。所以你的模型应该只是:
class Product < ActiveRecord::Base
attr_accessible :name, :price, :released_on
validates :name, uniqueness: true
end
它在您执行验证的控制器中并适当地处理它。示例控制器可能如下所示:
class ProductsController < ApplicationController
def create
@product = Product.new(params[:product])
if @product.valid?
@product.save
flash[:notice] = "Product created!"
redirect_to(@product) and return
else
render(:action => :new)
end
end
end
然后在您的视图中,您可能会将实际错误呈现给用户:
# app/views/products/new.html.erb
<%= error_messages_for(@product) %>
.. rest of HTML here ..
默认情况下, error_messages_for
不再包含在Rails中,而且它位于gem dynamic_form
有关显示错误的一般方法,请参阅此Rails指南:
http://guides.rubyonrails.org/active_record_validations.html#displaying-validation-errors-in-views
答案 1 :(得分:3)
正如Cody所提到的,不要在开始/救援中包装你的valites,因为validates方法只是告诉你的模型需要验证什么,它不是实际验证方法运行的地方。
然后,这是您的导入方法应该是什么样的:
def import(file)
CSV.foreach(file.path , headers:true) do |row|
product = Product.new(row.to_hash)
if product.save
# product valid and created
else
# invalid record here... you can inspect product.errors
end
end