1

Having trouble with this seemingly simple task of importing a CSV file via a Rake task, and storing in multiple tables.

My rake task:

desc "Imports the COGCC CSV file into wikifrac database"
task :import_cogcc => :environment do

    require 'csv'

    CSV.foreach('public/partial.csv', :headers => true) do |row|

        # create records in independent tables

        # create the Company object
        this_company_name = row['name'].strip!
        this_operator_num = row['operator_num']

        if !(Companies.exists?(:company_name => this_company_name))
          Companies.create(:company_name => this_company_name, :operator_num => this_operator_num)
        end
        thecompany = Companies.find(:first, :conditions => ["this_company_name = ?", this_company_name])
        company_id = thecompany.id

...

My Companies model:

class Companies < ActiveRecord::Base
  has_many :facilities, dependent: :destroy
  attr_accessor :company_name, :operator_num

  def initialize(company_name, operator_num)
    @operator_num = operator_num  
    @company_name = company_name  
  end

end

But when I run rake import_partial, I get this error:

rake aborted! ArgumentError: wrong number of arguments (1 for 2) wfrails/app/models/companies.rb:5:in initialize' wfrails/lib/tasks/import_partial.rake:47:in block (2 levels) in ' wfrails/lib/tasks/import_partial.rake:26:in `block in ' Tasks: TOP => import_cogcc

Can anyone tell me what's wrong with this? Have been going around and around with this; many similar examples in SO, but cannot quite solve my error....

rixter
  • 1,237
  • 3
  • 19
  • 32
  • http://stackoverflow.com/questions/8804868/why-is-overriding-activerecordbase-initialize-wrong – Brad Werth Aug 15 '14 at 20:16
  • 1
    Why are you overriding `initialize`? [ActiveRecord provides several ways](http://guides.rubyonrails.org/active_record_basics.html) to bulk initialize models with their attributes. Why are you adding instance variable to your model? Are those not meant to be stored in the database? The AR `create` method can't use the new `initialize` you created. – Nick Veys Aug 15 '14 at 20:19
  • 4
    Just get rid of your `initialize` method and all will work. – BroiSatse Aug 15 '14 at 20:21
  • 1
    you might want to consider using a transaction and create! so that you do not get models being created when the rake task fails – user3334690 Aug 15 '14 at 20:50
  • Thanks guys; removing the initialize did it... – rixter Aug 16 '14 at 04:28

1 Answers1

1

The error is because you are calling create with a hash in your rake task. The hash is counted as 1 object (the syntax you use has implicit curly braces around it, so you are really passing in {:company_name => this_company_name, :operator_num => this_operator_num}), whereas you have overridden the initialize method to take 2 arguments separately. Hence, it complaining it only find 1 parameter where it expects 2.

Easy way

Since you are using activerecord, I would do what BroiSatse says and just remove your initialize overridden method. This will allow the hash to work correctly, and will automatically set the attributes you send in.

Special case

If for some reason, you want to set those two variables as part of the initialization, I would make sure you call super so that the rest of the object is set correctly.

ruby def initialize(params={}) super self.operator_num = params[:operator_num] self.company_name = params[:company_name] end

But I only do this if I need these attributes set before I run any of my callbacks.

jstim
  • 2,432
  • 1
  • 21
  • 28