Ruby on Rails:验证CSV文件 [英] Ruby on Rails: Validate CSV file

查看:148
本文介绍了Ruby on Rails:验证CSV文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在导入CSV时遵循了RailsCast( http://railscasts.com/Episodes/396-importing-csv-and-excel ),我正在尝试验证要上传的文件是CSV文件.

Having followed the RailsCast on importing CSV (http://railscasts.com/episodes/396-importing-csv-and-excel), I am trying to validate that the file being uploaded is a CSV file.

我使用了宝石csv_validator来做到这一点,如此处 https://github.com/mattfordham所述/csv_validator

I have used the gem csv_validator to do so, as documented here https://github.com/mattfordham/csv_validator

所以我的模型如下:

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

但是我的系统仍然允许我选择导入非CSV文件(例如.xls),并且收到结果错误:invalid byte sequence in UTF-8.

But my system still allows me to select to import non-CSV files (such as .xls), and I receive the resulting error: invalid byte sequence in UTF-8.

有人可以告诉我为什么以及如何解决吗?

Can someone please tell me why and how to resolve this?

请注意,我正在使用Rails 4.2.6

Please note that I am using Rails 4.2.6

推荐答案

您可以创建一个新类,例如ContactCsvRowValidator:

You can create a new class, let's say 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

然后像这样使用它:

# 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

可以轻松修改此模式以适合您的需求.例如,如果需要在多个不同的模型上进行导入,则可以创建一个基本的CsvRowValidator,以提供诸如validate_fieldsinitializeerrors之类的基本方法.然后,您可以为所需的每个模型创建一个从CsvRowValidator继承的类,并实现自己的验证.

This pattern can easily be modified to fit your needs. For example, if you need to have import on several different models, you could create a base CsvRowValidator to provide basic methods such as validate_fields, initialize and errors. Then, you could create a class inheriting from this CsvRowValidator for each model you want, having its own validations implemented.

这篇关于Ruby on Rails:验证CSV文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆