# Recording errors

**URL:** <https://www.ruby-forum.com/t/recording-errors/173212>\
**Category:** Rails\
**Created:** [August 5, 2009, 1:09am UTC](https://www.ruby-forum.com/t/recording-errors/173212 "2009-08-05T01:09:32Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![DanC](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/77aa72/32.png) [@DanC](https://www.ruby-forum.com/u/DanC)\
**Post date:** [August 5, 2009, 1:09am UTC](https://www.ruby-forum.com/t/recording-errors/173212/1 "2009-08-05T01:09:32Z")

</div>

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/](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

---

<div class="post-metadata">

**Author:** ![DanC](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/77aa72/32.png) [@DanC](https://www.ruby-forum.com/u/DanC)\
**Post date:** [August 5, 2009, 9:30am UTC](https://www.ruby-forum.com/t/recording-errors/173212/2 "2009-08-05T09:30:34Z")

</div>

On Aug 5, 12:08 am, DanC [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> if @user.save!
> @user.roles << member_role
> else
> record_error(line)
> end
> 
> ```

This else statement will never execute since if save! fails it raises  
an exception. Did you want to use save instead ?

Fred

---

<div class="post-metadata">

**Author:** ![DanC](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/77aa72/32.png) [@DanC](https://www.ruby-forum.com/u/DanC)\
**Post date:** [August 5, 2009, 10:45am UTC](https://www.ruby-forum.com/t/recording-errors/173212/3 "2009-08-05T10:45:30Z")

</div>

Hi Fred,

You are right about the conditional statement being rubbish.

What I really want is to save users that pass the validations and any  
lines in the csv that fail to get skipped over, but remember the error  
that was generated.

Without rescue the whole action would fail.

I am just not sure how to record those errors and associate them with  
this particular import.

Dan

---

<div class="post-metadata">

**Author:** ![DanC](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/77aa72/32.png) [@DanC](https://www.ruby-forum.com/u/DanC)\
**Post date:** [August 5, 2009, 1:14pm UTC](https://www.ruby-forum.com/t/recording-errors/173212/4 "2009-08-05T13:14:08Z")

</div>

On Aug 5, 9:44 am, DanC [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Hi Fred,
> 
> You are right about the conditional statement being rubbish.
> 
> What I really want is to save users that pass the validations and any  
> lines in the csv that fail to get skipped over, but remember the error  
> that was generated.

Well if you use save rather than save! it won’t raise an exception if  
the record is invalid. If you want the individual errors they’ll be in  
your\_object.errors.

Fred
