0

I am migrating data from a database and getting an error I cannot understand. I am new to Ruby and am looking for both what is wrong with my code and also the most effective commands for debugging. I cannot even really read my error.

Here is my error:

/Users/skline/.rvm/gems/ruby-1.9.2-p136@rails3tutorial/gems/activemodel-3.0.6/lib/active_model/attribute_methods.rb:367:in `method_missing': undefined method `answer=' for #<Question:0x00000102d59758> (NoMethodError)
    from /Users/skline/.rvm/gems/ruby-1.9.2-p136@rails3tutorial/gems/activerecord-3.0.6/lib/active_record/attribute_methods.rb:46:in `method_missing'
    from ./script/migrate.rb:139:in `block (2 levels) in <main>'
    from /Users/skline/.rvm/gems/ruby-1.9.2-p136@rails3tutorial/gems/activerecord-3.0.6/lib/active_record/relation.rb:13:in `each'
    from /Users/skline/.rvm/gems/ruby-1.9.2-p136@rails3tutorial/gems/activerecord-3.0.6/lib/active_record/relation.rb:13:in `each'
    from ./script/migrate.rb:137:in `block in <main>'
    from ./script/migrate.rb:111:in `each'
    from ./script/migrate.rb:111:in `<main>'

Any tips for reading this error and for how to debug.

Note here is my code:

NetworkCommunications.all.each do |nc|
  if nc.NETWORK_COMM_TYPE_ID==1 && nc.SENDER_CONSUMER_ID != 0
    q = Question.new
    q.created_at = nc.LAST_MOD_TIME
    category = CommunicationInterestMapping.where(:COMMUNICATION_ID => nc.COMMUNICATIONS_ID).first
    if category
      cie = ConsumerInterestExpertLookup.find(category.CONSUMER_INTEREST_EXPERT_ID)
      if cie
        q.category = Category.find_by_name cie.CONSUMER_INTEREST_EXPERT_NAME
      else
        puts "No category"
      end
    end

    message = NetworkCommunicationsMessage.where(:COMMUNICATIONS_ID => nc.COMMUNICATIONS_ID).first
    q.title = message.SUBJECT
    q.description =  message.MESSAGE
    q.permalink = message.QUESTION_SLUG

    email = find_email_from_consumer_id(nc.SENDER_CONSUMER_ID)
    q.user = User.find_by_email email

    children = NetworkCommunications.where(:PARENT_COMMUNICATIONS_ID => nc.COMMUNICATIONS_ID)
    puts children

    if children
      children.each do |ncc|
        if ncc.NETWORK_COMM_TYPE_ID == 2
          q.answer = Answer.new
          q.answer.created_at = ncc.LAST_MOD_TIME
          message_a = NetworkCommunicationsMessage.where(:COMMUNICATIONS_ID => ncc.COMMUNICATIONS_ID).first
          q.answer.text = message_a.MESSAGE
          email_a = find_email_from_consumer_id(ncc.SENDER_CONSUMER_ID)
          q.answer.user = User.find_by_email email_a
        end
      end
    end

    begin
      q.save!
    rescue Exception => e
      puts "Exception: #{e} title: #{message.SUBJECT}"
    end
  end
end
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Spencer
  • 21,348
  • 34
  • 85
  • 121

3 Answers3

2

To read the stack dump, look at the first line then read downwards:

/Users/skline/.rvm/gems/ruby-1.9.2-p136@rails3tutorial/gems/activemodel-3.0.6/lib/active_model/attribute_methods.rb:367:in `method_missing': undefined method `answer=' for #<Question:0x00000102d59758> (NoMethodError)
    from /Users/skline/.rvm/gems/ruby-1.9.2-p136@rails3tutorial/gems/activerecord-3.0.6/lib/active_record/attribute_methods.rb:46:in `method_missing'
    from ./script/migrate.rb:139:in `block (2 levels) in <main>'

The first line tells you where the problem was triggered and why: In ActiveModel's attribute_methods method because no setter for answer was found in the object. This was triggered from a call in line 139 of your migrate.rb script. The trick with a stack trace is to read through it, looking for the scripts you've written. Odds are really good the problem is in our code so it's always good to start from the assumption the bug is ours.

if ncc.NETWORK_COMM_TYPE_ID == 2
  q.answer = Answer.new

is where the problem is. Your Question class doesn't have a setter for answer. Either you're missing or misspelled an attribute_accessor call or misspelled a def answer= method.

To debug I recommend using Ruby Debugger 1.9. gem install ruby-debug19. It's 1.9.2 studly and easy to use. You can set a breakpoint in your code, then run it from the command-line, which will run until the breakpoint is reached and will stop in the debugger. From there you can list the current lines using l, display the contents of variables using p or do a require 'pp' if you have pretty-printer installed. You can single-step into methods using s or step over them using n, for "next". There's also c to continue, c 100 to continue to a particular line number; 100 in that example. You can use b 100 to set a break-point at line 100, and then c to run, stopping at 100 every time. irb will drop you into IRB with the variables to that point already initialized so you can poke at them. There are lots of other commands, but those are the ones I use most often.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
0

It probably means you have defined the answer attribute for your question class:

class Question < ActiveRecord::Base
    attr_accessor :answer
    [...]
end

You should also learn how to use rdebug so that you can step through the code and figure this out without help.

Wes
  • 6,455
  • 3
  • 22
  • 26
0

I think your model Question doesn't have answer attribute. In this cast you can study how to debug rails app

megas
  • 21,401
  • 12
  • 79
  • 130