I am using restful_authentication in a rails app, but I also wanted to
let administrators create news users by piggybacking on the
restful_authentication function.
I decided to allow csv imports for creating members in a two step
process similar to this one,
http://goodbadtech.com/2009/05/13/ruby-on-rails-import-csv-data-into-database/
So I import the csv using PaperClip and then process it to create
users etc. I also use a rescue in case exceptions are thrown, but I
would like to record these errors for display after the entire csv has
been imported. I thought about creating a new model, ImportError that
belonged to import, so that each csv file could have a list of error
messages later on.
But I can’t get the recording part to work. Users are created and
stored, but the rescue action overrides everything else when errors
like duplicate entries come up.
here is my controller.
class ImportsController < ApplicationController
before_filter :check_administrator_role #protect controller from
anonymous users
def new
@import = Import.new
end
def create
@import = Import.new(params[:import])
respond_to do |format|
if @import.save!
flash[:notice] = 'CSV data was successfully imported.'
format.html { redirect_to(@import) }
else
flash[:error] = 'CSV data import failed.'
format.html { render :action => "new" }
end
end
end
def show
@import = Import.find(params[:id])
end
def proc_csv
@import = Import.find(params[:id])
lines = parse_csv_file(@import.csv.path)
#lines.shift #comment this line out if your CSV file doesn’t
contain a header row
if lines.size > 0
@import.processed = lines.size
lines.each do |line|
new_user(line)
end
@import.save
flash[:notice] = “CSV data processing was successful.”
redirect_to :action => “show”, :id => @import.id
else
flash[:error] = “CSV data processing failed.”
render :action => “show”, :id => @import.id
end
end
private
def parse_csv_file(path_to_csv)
lines = []
#if not installed run, sudo gem install fastercsv
#http://fastercsv.rubyforge.org/
require 'fastercsv'
FasterCSV.foreach(path_to_csv) do |row|
lines << row
end
lines
end
def new_user(line)
params = Hash.new
params[:user] = Hash.new
params[:user][“name”] = line[0]
params[:user][“email”] = line[1]
params[:user][“password”] = random_password
params[:user][“password_confirmation”] = params[:user]
[“password”]
@user = User.new(params[:user])
member_role = Role.find_by_rolename(‘member’)
if @user.save!
@user.roles << member_role
else
record_error(line)
end
rescue ActiveRecord::RecordInvalid
end
def random_password(size = 8)
chars = ((‘a’…‘z’).to_a + (‘0’…‘9’).to_a) - %w(i o 0 1 l 0)
(1…size).collect{|a| chars[rand(chars.size)] }.join
end
def record_error(line)
params = Hash.new
params[:import_error] = Hash.new
params[:import_error][“import_id”] = @import.id
params[:import_error][“name”] = line[0]
params[:import_error][“email”] = line[1]
params[:import_error][“error_message”] = flash[:error]
@import_error = User.new(params[:import_error])
@import_error.save!
end
end
any advice will be appreciated.
Thanks,
Dan