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

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

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 Jones

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 Jones 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