在Rails中导出不成功的CSV时显示闪存

时间:2015-12-13 09:21:58

标签: ruby-on-rails ruby ruby-on-rails-4

我的Rails应用程序中有一个有效的CSV导入功能。

item.rb的

 #CSV Import Function
 def self.import(file)
   CSV.foreach(file.path, headers: true) do |row|
     Item.create! row.to_hash
   end  
 end

items_controller.rb

def import
  current_user.items.import(params[:file]) 
  flash[:success] = "Import Successful"
  redirect_to spage3_path 
end

这对我很有用。但是,当导入不成功时(我在我的Item模型的某些字段上有一些验证)应用程序崩溃。在这种情况下,我只想向用户显示flash [:danger]。为此,这就是我修改控制器的方法,但现在我每次都得到flash [:danger]

items_controller.rb

def import
  if current_user.items.import(params[:file]) 
    flash[:success] = "Import Successful"
    redirect_to spage3_path
  else
    flash[:danger] = "Error Encountered"
    redirect_to spage3_path
  end  
end

请告知我哪里弄错了。感谢

3 个答案:

答案 0 :(得分:1)

如果对象验证失败,

.create!会引发异常。您可以处理此案例以避免应用程序崩溃。 您可以在保存之前检查对象是否有效。

  • 如果有效:保存并继续解析CSV
  • 如果无效:返回false并停止解析CSV

一个想法可能是:

item.rb的

 #CSV Import Function
 def self.import(file)
   CSV.foreach(file.path, headers: true) do |row|
     item = Item.new(row.to_hash)
     # exit from the block it item is not valid
     return false unless item.valid?

     # save the item only if is valid
     item.save
   end  
 end

使用此方法,您可以按原样保留控制器。

items_controller.rb

def import
  if current_user.items.import(params[:file]) 
    flash[:success] = "Import Successful"
    redirect_to spage3_path
  else # when return false show flash[:danger] to the user
    flash[:danger] = "Error Encountered"
    redirect_to spage3_path
  end  
end

答案 1 :(得分:1)

如果您将其设置为类< / em>方法。

两者之间的区别在于 class 方法调用该类,而实例方法在已调用的类中运行:

import

您需要以下内容:

虽然你提到它正在发挥作用,但我认为为#app/models/item.rb class Item < ActiveRecord::Base def self.import #class method called by Item.import end def import #instance method called by @item.import end end 调用类方法是不好的做法...

current_user.items

这将使您能够致电:

#app/models/user.rb
class User < ActiveRecord::Base
   has_many :items do
       def import(file)
         CSV.foreach(file.path, headers: true) do |row|
            item = Item.new row.to_hash #-> this might be best as "self.new" to invoke the instance of Item model
            return item.errors unless item.save 
         end  
       end
   end
end

-

这里有几点需要注意。

首先,我使用ActiveRecord Association Extension作为def import message = (@file = current_user.items.import(params[:file])) ? [:notice, "Import Successful"] : [:alert, @file] redirect_to.send(spage3_path, "#{message[0]}: #{message[1]}") end 方法。我这样做是因为你正在调用它; import

坦率地说,我不知道你当前的设置是如何工作的 - 如果你打电话给current_user.items.import - 我希望应用程序能够回复错误。你在current_user.items.import模型的集合上调用import,我希望它只能用于实例方法,绝对不是类。

其次,您必须将异常返回给控制器。如果您没有收到任何异常消息,您希望如何调试?我的代码为您提供了如何返回消息,尽管它可能不正确。

答案 2 :(得分:0)

如果存在验证错误,

create会引发异常。请改用def self.import(file) CSV.foreach(file.path, headers: true) do |row| return :failed unless Item.create(row.to_hash) end end 并检查返回值:

def import
  if current_user.items.import(params[:file]) == :failed
    flash[:danger] = "Error Encountered"
  else
    flash[:success] = "Import Successful"
  end  

  redirect_to spage3_path
end

将控制器更改为:

const {Table, Column, Cell} = FixedDataTable;