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)
--
Posted via http://www.ruby-forum.com/.
On Sep 16, 2009, at 6:39 AM, Bill Devaul 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 )> > 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) > -- > Posted via http://www.ruby-forum.com/. > > >
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 -- Posted via http://www.ruby-forum.com/.
> 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 Hallstrom wrote:> Oh, could be... there''s probably another method that will give you > back key/value pairs for FasterCSV::Row. > > -philipIt looks like each_pair and each are identical methods. I can instance.each {|k,v| k = v } no problem. Any other ideas? -- Posted via http://www.ruby-forum.com/.
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
On Sep 16, 3:31 pm, Bill Devaul
<rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org>
wrote:> Philip Hallstrom 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?
> --
> Posted viahttp://www.ruby-forum.com/.
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
--
Posted via http://www.ruby-forum.com/.