patrick
patrick

Reputation: 1042

How to override created_at field in model when importing a CSV?

I'm importing a CSV full of waitlist signups into my database with previous created dates, how can I import them while keeping their initial dates vs. having them all show the same date of importing?

I get the error: Rails can't mass-assign protected attributes for id, created_at

The code:

 csv_file = params[:csv][:file].read
    csv = CSV.parse(csv_file, :headers => false) 
    csv.each do |row|
       Model.create!(:email => row[0], :created_at => row[1])    
    end    

Upvotes: 7

Views: 9150

Answers (3)

Jon Kern
Jon Kern

Reputation: 3235

Maybe you could do something like this:

csv.each do |row|
   doc = Model.create!(:email => row[0])
   doc.update(created_at: row[1])
end

I needed to do something similar, going back through organizations, and updating the creation based on the earliest user that registered (if applicable). (The organization ID was a custom string :-)

So you can see how the update command works... And you can see the clever trick to use a BSON id to get the date.

Org.all.to_a.collect do |o|
  u = o.users.first
  if u
    o.update(created_at: Time.parse(u.id.generation_time.strftime('%Y-%m-%d %H:%M')))
  else
    o.update(created_at: Time.now.utc)
  end
end

Upvotes: 0

Peter Berg
Peter Berg

Reputation: 6206

In Rails 4:

attr_accessible is no longer used and including it a the top of a model will likely break your code. Merely including :created_at in the args passed to create! should do it.

Turning @Ghoti's comment into an answer here to give it more visibility

Upvotes: 17

rogeliog
rogeliog

Reputation: 3692

You need to add the desired column to the attr_accessible

class Tutorial < ActiveRecord::Base
  attr_accessible :created_at
end

Upvotes: 6

Related Questions