新手问题 在用 roo 导入 CSV,这段代码的导入过程这部分的理解不是特别清晰,求讲解一下!

Catherine · 2015年11月19日 · 最后由 zlx_star 回复于 2015年11月20日 · 1983 次阅读

这是表结构

def change
    create_table :products do |t|
      t.string :name
      t.date :released_on
      t.decimal :price, :precision => 2, :scale => 8

      t.timestamps
    end
def self.import(file)
    spreadsheet = open_spreadsheet(file)
    header = spreadsheet.row(1)
    (2..spreadsheet.last_row).each do |i|
      row = Hash[[header, spreadsheet.row(i)].transpose]
      product = find_by_id(row["id"]) || new
      product.attributes = row.to_hash.slice(*accessible_attributes)
      product.save!
    end
  end

  def self.open_spreadsheet(file)
    case File.extname(file.original_filename)
    when ".csv" then Csv.new(file.path, nil, :ignore)
    when ".xls" then Excel.new(file.path, nil, :ignore)
    when ".xlsx" then Excelx.new(file.path, nil, :ignore)
    else raise "Unknown file type: #{file.original_filename}"
    end
  end
(2..spreadsheet.last_row)
  1. 这个迭代为什么这样写 spreadsheet 现在不是一个 csv 或者 xls 或者 xlsx 的文件对象么,2 到这个文件对象的最后一排?感觉好别扭 = =
  2. 为什么要用 transpose 把表格里的行和列换位?
  3. 没有用过,但 find_by_id 应该是动态查询方法吧,那 row['id'] 是什么?
  4. attributes 可以像哈希那样用键值对来对应字段和值插入数据库,但 accessible_attributes 是所有可访问的属性,加*是啥作用..
  1. 第一行可能是标题,可以用常量代替数字
  2. 可以直接把数据转化成 { 标题 => value } 的形式,方便后续操作
  3. 同上,row 是刚刚构造出来的 Hash , 大概是这么个格式 : { 'id' => 10002, 'Name' => 'apple', 'price' => 10, 'released_on' => '2015-10-18' }
  4. * 是为了把 数组拆开作为参数

这里很多都是 Ruby 的基本用法,建议可以看看 ruby-doc.org 的文档

#1 楼 @zlx_star 谢谢,基本搞明白了。。ruby 没有指针这个东西,但用*是把 accessible_attributes 这里的几个参数变为数组....太狡诈了!

#2 楼 @catherine 我觉得用巧妙比较合适

需要 登录 后方可回复, 如果你还没有账号请 注册新账号