最近在搞 ROR,搞了快有一段时间了。但是拿到一个东西还是不知该从那里做起。 如果用 ruby 搞一个 terminate 的小程序,在不考虑代码风格等的情况下,还是很快能搞定的。但是却不知道如何迁移到 rails 上(毕竟命令行只是给 programmer 来用的啊)
求教了~
推荐你看看:《Agile Web Development with Rails》抄书笔记 http://ruby-china.org/topics/10478
如果英文没问题,看 Agile Web Development with Rails 最新版原版是最好的起步路线 http://pragprog.com/book/rails4/agile-web-development-with-rails
我举个简单的例子,各位帮忙分析下,我该如何下手: 最近给前台做一个考勤的东西。这个考勤是从考勤机里面导出来的一个 excel。(不去说考勤机是否提供我做的这个功能,因为这个事情无从知晓)然后前台就去一天天的对每个人的考勤情况,并且记录到一个 excel 表格中(两个 excel 格式完全不一样)然后统计加班的时间,倒休,请假等信息。 现在,她想直接上传那个最原始的 excel 信息(每一行就是一条打卡记录),然后我这边分析这个 excel(因为打卡跟门禁是同一个认证。所以一天可能有很多次打卡信息),取最早的和最晚的打卡时间。记录到第二个 excel 中,以此类推。取每个月的。以及每个人的。现在我是这么做的 :1、定义了一个 Fingerprint model,这个对应的是基础信息里面的一条打卡记录。 2、生成了 Fingerprints_controller,并在这个类中加入了一个 upload_excel 的 action,此 action 完成 excel 的上传,同时,读取 excel,写入到 mysql 数据库中。
3:、结下来,不知道该怎么搞了~ 问题: 1、我在 controller 中写了好多好多的业务逻辑代码(在 java 中 controller 很少写业务逻辑的),想问这样正常吗? 2、activeRecor 的插入很慢。5000 多条记录大概 10 分钟左右才跑完,不知道是不是我程序有问题。 3、因为要导出的 excel 的实体模型完全跟基础数据不一样,我是否应该再定义一个 Model。 下面是 controller 的文件上传部分代码,求指教:
def upload_excel
excel = params[:upload]
puts excel['datafile'].content_type
file_name = excel['datafile'].original_filename if (excel['datafile'] != '')
file = excel['datafile'].read()
file_type = file_name.split(".").last
if file_type and 'xls' != file_type
flash[:alert] = '文件类型不正确!只允许传xls扩展类型的文件!'
redirect_to :action => :upload_view and return
end
new_file_name = file_name
new_file_name_with_type = "#{new_file_name}.#{file_type}"
excel_root = get_upload_file_path
if (!Dir.exist?(excel_root))
Dir.mkdir(excel_root, 777)
end
File.open( get_upload_file_path+new_file_name, 'wb') do |f|
f.write(file)
end
flash[:info] = file_name
workbook = Spreadsheet.open( get_upload_file_path+new_file_name)
sheet = workbook.worksheets[0]
puts sheet.count
if sheet
sheet.each do |row|
finger_print = Fingerprint.new
finger_print.dept_name = row[0]
finger_print.employee_name = row[1]
finger_print.employee_no = row[2]
finger_print.fp_time = row[3]
finger_print.machine = row[4]
finger_print.no = row[5]
finger_print.pattern = row[6]
finger_print.card_no = row[7]
finger_print.file_name = new_file_name
finger_print.save
end
end
redirect_to :action => :upload_view and return
end
下面是 route,不知这样配置是否优雅:
get "fingerprints/upload_view" => "fingerprints#upload_view"
post "fingerprints/upload_excel" => "fingerprints#upload_excel"
resources :fingerprints
前半部分文件上传,可以交给 carrierwave 这样的 gem 解决。
后面插入部分,基本没问题,就是 ActiveRecord 写法可以改进一下:
Fingerprint.create
:dept_name => row[0]
:employee_name => row[1]
...
效率问题我现在不用 ActiveRecord 不清楚,10 分钟有点太慢(120ms/record),一般插入应该十几毫秒。改进办法:
controller 逻辑过多应该抽取到 Model 或者 lib
我可以这么理解吧。其实在做 rails 的时候。一个 model 对应一个 controller 到 view,跟 model 相关的简单逻辑,例如:crud,这些可以放在 model 里面做。比如有更负责的逻辑。例如下订单。处理一些别的数据(跟 model 对应不起来的)就可以放在 lib 里了。另外,controller 对应的 rest url 有 edit,view,delete,create。如果要加跟这些无关的。例如上传一个 excel。我这个 action 放在对应的 aiction 里面是否可以?