Ruby on rails RubyonRails:验证CSV文件

Ruby on rails RubyonRails:验证CSV文件,ruby-on-rails,ruby,excel,csv,ruby-on-rails-4,Ruby On Rails,Ruby,Excel,Csv,Ruby On Rails 4,在遵循RailsCast导入CSV()之后,我尝试验证正在上载的文件是否为CSV文件 我使用了gemcsv\u验证器,如本文所述 我的模型是这样的: class Contact < ActiveRecord::Base belongs_to :user attr_accessor :my_csv_file validates :my_csv_file, :csv => true def self.to_csv(options = {}) CSV.gener

在遵循RailsCast导入CSV()之后,我尝试验证正在上载的文件是否为CSV文件

我使用了gem
csv\u验证器
,如本文所述

我的模型是这样的:

class Contact < ActiveRecord::Base
  belongs_to :user

  attr_accessor :my_csv_file
  validates :my_csv_file, :csv => true

  def self.to_csv(options = {})
    CSV.generate(options) do |csv|
        csv << column_names
        all.each do |contact|
            csv << contact.attributes.values_at(*column_names)
        end
    end
  end
    def self.import(file, user)
    allowed_attributes = ["firstname","surname","email","user_id","created_at","updated_at", "title"]
    CSV.foreach(file.path, headers: true) do |row|
        contact = find_by_email_and_user_id(row["email"], user) || new
        contact.user_id = user
        contact.attributes = row.to_hash.select { |k,v| allowed_attributes.include? k }
        contact.save!
    end
  end
end
# contact.rb
def self.import(file, user)
  allowed_attributes = ["firstname","surname","email","user_id","created_at","updated_at", "title"]
  if file.path.split('.').last.to_s.downcase != 'csv'
    some_method_which_handle_the_fact_the_file_is_not_csv!
  end
  CSV.foreach(file.path, headers: true) do |row|
    row_validator = ContactCsvRowValidator.new(row)
    errors = row_validator.errors
    if errors.present?
      some_method_to_handle_invaid_row!(row)
      return
    end

    # other logic
  end
end
class联系人true
定义self.to_csv(选项={})
CSV.生成(选项)do | CSV|

csv您可以创建一个新类,比如说
ContactCsvRowValidator

class ContactCsvRowValidator

  def initialize(row)
    @row = row.with_indifferent_access # allows you to use either row[:a] and row['a']
    @errors = []
  end

  def validate_fields
    if @row['firstname'].blank?
      @errors << 'Firstname cannot be empty'
    end

    # etc.
  end

  def errors
    @errors.join('. ')
  end
end

可以轻松修改此模式以满足您的需要。例如,如果需要在几个不同的模型上导入,可以创建一个基本的CsvRowValidator来提供基本方法,例如
验证\u字段
初始化
错误
。然后,您可以为所需的每个模型创建一个继承自此CsvRowValidator的类,并实现其自己的验证。

您可以创建一个新类,比如说
ContactCsvRowValidator

class ContactCsvRowValidator

  def initialize(row)
    @row = row.with_indifferent_access # allows you to use either row[:a] and row['a']
    @errors = []
  end

  def validate_fields
    if @row['firstname'].blank?
      @errors << 'Firstname cannot be empty'
    end

    # etc.
  end

  def errors
    @errors.join('. ')
  end
end

可以轻松修改此模式以满足您的需要。例如,如果需要在几个不同的模型上导入,可以创建一个基本的CsvRowValidator来提供基本方法,例如
验证\u字段
初始化
错误
。然后,您可以为所需的每个模型创建一个继承自此CsvRowValidator的类,并实现其自己的验证。

您可以在尝试导入文件之前检查文件的扩展名:
file.path.split('..).last.to_.downcase==“csv”
@MrYoshiji谢谢您的评论,我还想验证某些列中的数据,虽然这个gem(应该)允许我这么做。这个gem允许您检索列中的数据,但是您需要制定逻辑来“验证列中的数据”。如果你想知道从哪里开始,我可以发布一个答案。你可以发布一个答案吗?你可以在尝试导入文件之前检查文件的扩展名:
file.path.split('.')。last.to_.downcase==“csv”
@MrYoshiji谢谢你的评论,我还想验证某些列中的数据,这是我的建议(应该)允许我这么做这个gem允许你检索列中的数据,这是你的责任,你需要在列中建立“验证数据”的逻辑。如果你想知道从哪里开始,我可以发布一个答案,你可以发布一个答案吗