Search code examples
rubyactiverecordfilemaker

Ruby + ActiveRecord: Can't write to database


I'm writing a script in Ruby for work. Our company uses FileMaker Pro for its database, and as far as I can tell, the most painless way to get information from the FileMaker database into a sqlite3 database is to export from FileMaker into a tab-delimited text file, then parse the file with Ruby.

The code sorts the tab-delimited text file and places each individual database listing into a position in an array. Then, it goes through each array position and breaks it down further into another array, such that in all the arrays, position 1 is the part number, 2 is the location, and so on and so forth. That part of the code works just great.

The part that's giving me fits is the part that uses ActiveRecord to write the sub-array to a sqlite3 table. Here's the offending code:

Partsdb.create(
                    :item_number => record_array[1], 
                    :location => record_array[2],
                    :quantity => record_array[3],
                    :make => record_array[4],
                    :year => record_array[5],
                    :model => record_array[6],
                    :serial => record_array[7],
                    :volt => record_array[8],
                    :phase => record_array[9],
                    :weight => record_array[10],
                    :list_price => record_array[11],
                    :sold => record_array[12],
                    :image_path => record_array[13],
                    :short_desc => record_array[14],
                    :long_desc => record_array[15],
                    :junk => record_array[16]
                )

I've required 'rubygems' and 'active_record', so it's not that. Here's the table declaration that I did in the sqlite3 terminal:

CREATE TABLE parts_info(item_number INTEGER PRIMARY KEY ASC, location TEXT, quantity INTEGER, make TEXT, year INTEGER, model TEXT, serial TEXT, volt INTEGER, phase INTEGER, weight INTEGER, list_price REAL, sold INTEGER, image_path TEXT, short_desc TEXT, long_desc TEXT, junk TEXT);

... and lastly, here's the error message that I get in my terminal when I try to run the script:

john@ubuntu:~/Desktop/idealm_db_parser$ ruby test.rb
/usr/local/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.4/lib/active_record/connection_adapters/sqlite_adapter.rb:295:in `table_structure': Could not find table 'partsdbs' (ActiveRecord::StatementInvalid)
    from /usr/local/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.4/lib/active_record/connection_adapters/sqlite_adapter.rb:186:in `columns'
    from /usr/local/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.4/lib/active_record/base.rb:679:in `columns'
    from /usr/local/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.4/lib/active_record/persistence.rb:284:in `attributes_from_column_definition'
    from /usr/local/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.4/lib/active_record/locking/optimistic.rb:62:in `attributes_from_column_definition'
    from /usr/local/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.4/lib/active_record/base.rb:1394:in `initialize'
    from /usr/local/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.4/lib/active_record/base.rb:496:in `new'
    from /usr/local/ruby/lib/ruby/gems/1.9.1/gems/activerecord-3.0.4/lib/active_record/base.rb:496:in `create'
    from test.rb:36:in `block (2 levels) in <main>'
    from test.rb:30:in `each'
    from test.rb:30:in `block in <main>'
    from test.rb:25:in `glob'
    from test.rb:25:in `<main>'

TRWTF is the 4th line in the error output - 'Could not find table 'partsdbs' (ActiveRecord::StatementInvalid). I've tried calling the table several different things, but it appends an 's' to the end of the table's name every time in the error output.

Any and all help would be greatly appreciated. I'm relatively new to programming, I've only been using Ruby for about two weeks, and I've been messing with ActiveRecord for about 3 days, so I'm still a little wet behind the ears.

Thanks for reading.


Solution

  • First off I'd recommend using FasterCSV to parse this rather than using your array. This is just so you don't have to remember what number matches up with each field.

    Secondly, your model must have the singularized + "classy" name of the table. This is so that when you call create on the model, Active Record will map that to the correct table. For example, if you have a Post model, it's reasonably expected that you also have a posts table to go along with it.

    In this case, this isn't possible because of how your table is named. To force the table name, use set_table_name in your model like this:

    class Part < ActiveRecord::Base
      set_table_name :parts_info
    end
    

    I've also taken the liberty of changing the class name to something more Ruby-esque too. You don't need to say it's a "db", that should be implicit.