user2711286
user2711286

Reputation: 141

Getting UnknownAttributeError in rake using CSV, attribute exists in rails app

I'm trying to bulk load a CSV file with a rake task in ruby on rails 5.

I have a simple model that will be a list of movies. I have the rails app running and can successfully create a new movie w/ the web app. When I run the rake task, it fails with UnknownAttributeError: unknown attribute 'Title' for Movie

here's my schema:

 create_table "movies", force: :cascade do |t|
  t.string   "Title"
  t.string   "Genre"
  t.string   "Rating"
  <snip>
 end

here's my create method (straight out of scaffolding...)

def create
  @movie = Movie.new(movie_params)

  respond_to do |format|
    if @movie.save
      format.html { redirect_to @movie, notice: 'Movie was successfully created.' }
      format.json { render :show, status: :created, location: @movie }
    else
      format.html { render :new }
      format.json { render json: @movie.errors, status: :unprocessable_entity }
    end
  end
end

here's my rake task:

desc "bulk load movies in the db"
task :upload_movies => [ :environment] do
  require 'csv' 

  f = "#{Rails.root}/tmp/movies.csv"

  raise "#{f} does not exist. Stoping import of movies" if !File.exists?(f)

  CSV.foreach(f, :headers => true) do |row|
    Movie.create!(row.to_hash)
  end
end

when I add movie via the app, the server console shows it working correctly like this:

(0.1ms) BEGIN SQL (1.3ms) INSERT INTO "movies" ("Title", "Genre", "Rating", "Lead", "Director", "Year", "Type", "Duration", "Theater", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING "id" [["Title", "the ballerina"], ["Genre", "sci fi"], ["Rating", "PG"], ["Lead", "random"], ["Director", "local"], ["Year", 2010], ["Type", "3D"], ["Duration", 90], ["Theater", "3/4"], ["created_at", 2016-12-24 15:05:21 UTC], ["updated_at", 2016-12-24 15:05:21 UTC]] (0.6ms) COMMIT Redirected to http://localhost:3000/movies/1

the top of my CSV file looks like this:

Title,Genre,Rating,Lead,Director,Year,Type,Duration,Theater
The Avengers: Age of Ultron 3D,Action,PG-13,Robert Downey Jr.,Joss Whedon,2015,3D,141,3/4

Here's the output of the rake task -- (I ran migrate for this example, just so this community would know my db is up to date...)

$ rake db:migrate
$ rake upload_movies
rake aborted!
ActiveModel::UnknownAttributeError: unknown attribute 'Title' for Movie.
/Users/ustonma/dev/stone/gl7movies/lib/tasks/movieUpload.rake:11:in `block (2 levels) in <top (required)>'
/Users/ustonma/dev/stone/gl7movies/lib/tasks/movieUpload.rake:10:in `block in <top (required)>'
Tasks: TOP => upload_movies
(See full trace by running task with --trace)
$ 

What am I missing? -thanks.

Upvotes: 1

Views: 298

Answers (3)

user2711286
user2711286

Reputation: 141

this was actually a problem with encoding of the CSV file. The file was saved using MS Excel with the format at CSV - UTF-8 (Comma delimited) (.csv)

When CSV.foreach started reading the file the first position of the file is a byte string indicating UTF-8. I used text mate to "save as" Unicode - UTF-8 and it worked. I also used excel to save as Comma Separated Values (.csv) and it also worked.

CSV in Ruby (2.3.1) on Rails 5 doesn't seem to like that that other UTF-8 encoding.

Upvotes: 0

IDIR GACI
IDIR GACI

Reputation: 54

can you try to see the columns of your Movie table created on migration?

rails c
Movie.new 

and show us the result

Upvotes: 0

Joel Blum
Joel Blum

Reputation: 7878

Are you sure the hash you try to create the movie with is valid? for example if Title is capital lettered it will blow up activerecord. Try it like this perhaps:

  {title: row[0], genre: row[1], ...}

Upvotes: 0

Related Questions