Removing eval from seed.rb code

I have written the below code in my seed.rb file. It takes my old data
in tab delimited format and brings it into the Rails database.

I want to remove the eval statement as I understand there are problems
with eval.

Any suggestions are appreciated.

seed.rb

#TODO move require and plant class to helper
#TODO do not use eval if possible
require ‘FasterCSV’

class Plant

def self.grow (model, filename, datamap, headers = true)

Kernel.const_get(model).delete_all

table = FasterCSV.table(filename, {
   :headers => headers,
   :header_converters => :symbol,
   :col_sep => "\t" # need the double quotes
   })

table.each do |row|
  record = eval datamap
end

end

end

Plant.grow(
“Business”,
File.join(File.dirname(FILE), ‘vendor.db’),
“Business.create(
:address => row[:vendoraddress],
:city => row[:vendorcity],
:email_general => row[:vendoremail],
:fax => row[:faxnumber],
:name => row[:vendorname],
:old_vendorid => row[:vendorid],
:phone => row[:vendorphone],
:sales_tax_rate => row[:vendorsalestax],
:zip_code => row[:vendorzipcode]
)”,
true)

On Sep 16, 2009, at 6:39 AM, Bill D. wrote:

I have written the below code in my seed.rb file. It takes my old
data
in tab delimited format and brings it into the Rails database.

I want to remove the eval statement as I understand there are problems
with eval.

Any suggestions are appreciated.

I’m sure there’s a more efficient way of re-mapping the fields, but
the below should work.

class Plant

def self.grow (model_name, filename, field_mappings, headers = true)

 the_model = Kernel.const_get(model_name)
 the_model.delete_all

 table = FasterCSV.table(filename, {
   :headers => headers,
   :header_converters => :symbol,
   :col_sep => "\t" # need the double quotes
 })

 table.each do |row|
   mapped_fields = {}
   row.each_pair{|k,v| mapped_fields[field_mappings[k.to_sym]] = v}
   record = the_model.create(mapped_fields)
 end

end

end

Plant.grow(
“Business”,
File.join(File.dirname(FILE), ‘vendor.db’),
{:address => :vendoraddress,
:city => :vendorcity,
:email_general => :vendoremail,
:fax => :faxnumber,
:name => :vendorname,
:old_vendorid => :vendorid,
:phone => :vendorphone,
:sales_tax_rate => :vendorsalestax,
:zip_code => :vendorzipcode},
true
)

Thanks for the reply. That definitely gets rid of the eval.

When I run that code I’m seeing:

rake aborted!
undefined method `each_pair’ for #FasterCSV::Row:0x2638dbc

I guess that method is not defined for the FasterCSV::Row class.

I will take another look this afternoon.

Oh, could be… there’s probably another method that will give you
back key/value pairs for FasterCSV::Row.

-philip

Philip H. wrote:

Oh, could be… there’s probably another method that will give you
back key/value pairs for FasterCSV::Row.

-philip

It looks like each_pair and each are identical methods. I can
instance.each {|k,v| k = v } no problem.

Any other ideas?

Thanks for the reply. That definitely gets rid of the eval.

When I run that code I’m seeing:

rake aborted!
undefined method `each_pair’ for #FasterCSV::Row:0x2638dbc

I guess that method is not defined for the FasterCSV::Row class.

I will take another look this afternoon.

Bill

The standard idiom here is to have grow take a block, thus:

def self.grow (model_name, filename, headers = true)
Kernel.const_get(model).delete_all
table = FasterCSV.table(filename, {
:headers => headers,
:header_converters => :symbol,
:col_sep => “\t” # need the double quotes
})
table.each do |row|
yield(row)
end
end

and then call with:

Plant.grow(…params here…) do |row|
Business.create(
:address => row[:vendoraddress],
:city => row[:vendorcity],
:email_general => row[:vendoremail],
:fax => row[:faxnumber],
:name => row[:vendorname],
:old_vendorid => row[:vendorid],
:phone => row[:vendorphone],
:sales_tax_rate => row[:vendorsalestax],
:zip_code => row[:vendorzipcode]
)
end

–Matt J.

On Sep 16, 3:31 pm, Bill D. [email protected]

That worked great! Thanks for clearing up the idiomatic usage. I have
not quite wrapped my head around it yet, but look forward to learning
more.

For the record, here’s the working code:

#TODO move require and plant class to helper
#DONE do not use eval if possible – Possible thanks to Matt J. on
ruby-forum.com
require ‘FasterCSV’

class Plant

def self.grow (model, filename, headers = true)
Kernel.const_get(model).delete_all
table = FasterCSV.table(filename, {
:headers => headers,
:header_converters => :symbol,
:col_sep => “\t” # need the double quotes
})
table.each do |row|
yield(row)
end
end

end

Plant.grow(“Business”, File.join(File.dirname(FILE), ‘vendor.db’))
do |row|
Business.create(
:address => row[:vendoraddress],
:city => row[:vendorcity],
:domain_name => row[:vendordomainname].to_s.gsub(/^(www.)+([^
])./, ‘\2’),
:email_general => row[:vendoremail],
:fax => row[:faxnumber],
:iadm_member => row[:iadm],
:name => row[:vendorname],
:old_vendorid => row[:vendorid],
:phone => row[:vendorphone],
:sales_tax_rate => row[:vendorsalestax],
:zip_code => row[:vendorzipcode]
)
end

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs