Noel Frostpaw
Noel Frostpaw

Reputation: 3999

unexpected to_f call

I'm currently creating an action that accepts a file from the user and reads the file line by line. Each line contains several words, seperated by a comma. The idea is to read each line, convert the line into an array of strings and then process each word individually.

I have created a basic class called Word, which has just an ID and value. I also have a basic class called Synonym, which has an ID, value and word_id to link to a word.

I receive an exception when parsing the words:

undefined method `to_f' for
#<Array:0x7ff6627074d8>

This is the code causing the problem for me:

# Processes the uploaded file from the upload form and extracts
  # all relevant information from the file to store it in the database
  def process_upload
    path = params[:file].tempfile.path
    open(path).each do |line|
      words = line.trim.split(',')
      first_word = words.first
      # Check if the word already exists as a synonym. If the word is a known synonym, save the
      # remaining words as synonyms for the parent word. But only save these words if they don't
      # exist yet
      if !Synonym.find_by_value(first_word).blank?
        parent_id = Synonym.find_by_value(first_word).word_id
        words.each do |word|
          Synonym.create(:value => word, :parent_id => parent_id) if Synonym.find_by_value(word).blank?
        end
      end

      # Check if the first word is already known as a word inside the application. If the first word is already
      # a known word, append all remaining words to the word as a synonym, but only if they don't exist yet.
      if !Word.find_by_value(first_word).blank?
        words.each do |word|
          parent_id = Word.find_by_value(first_word).id
          if (word != first_word) and Synonym.find_by_value(word).blank?
            Synonym.create(:value => word, :parent_id => parent_id)
          end
        end
      end

      # The word is not a known synonym, and not a known word. Create the word in the database and
      # append all remaining words to the database as synonyms.
      word = Word.create(:value => first_word)
      words.each do |w|
        if w.eql? word.value
          Synonym.create :value => w, :parent_id => word.id
        end
      end
    end
  end

The problem occurs on the last part, Word.create(:value => first_word) I receive an exception here that tries to cast it to a float for some reason, but I have no idea why.

The migration schema' for both models:

class CreateWords < ActiveRecord::Migration
  def self.up
    create_table :words do |t|
      t.string :value, :null => false
      t.timestamps
    end
  end

  def self.down
    drop_table :words
  end
end

class CreateSynonyms < ActiveRecord::Migration
  def self.up
    create_table :synonyms do |t|
      t.integer :word_id, :null => false
      t.string :value, :null => false
      t.timestamps
    end
  end

  def self.down
    drop_table :synonyms
  end
end

What am I missing?

Upvotes: 1

Views: 485

Answers (1)

Noel Frostpaw
Noel Frostpaw

Reputation: 3999

In regards to the above comments, I found out what was causing this:

If you rely on the Classifier gem from rubyforge or rubygems, it will overwrite the Array#sum method. Since these gems are loaded AFTER rails is loaded, they overwrite this method for ActiveRecord as well, which causes errors.

There are branches of this gem avaialble that keep track of all this, but in the end, I decided to use the 'Ankusa' gem instead, as it was more suited to handeling large batches of text data and had better integrated support for saving the state.

Upvotes: 2

Related Questions