Ruby的新手试图学习如何调试

时间:2011-04-20 23:16:35

标签: ruby-on-rails ruby database

我正在从数据库迁移数据并收到我无法理解的错误。我是Ruby的新手,我正在寻找我的代码有什么问题以及最有效的调试命令。我甚至无法真正阅读我的错误。

这是我的错误:

/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>'

有关阅读此错误以及如何调试的提示。

请注意,这是我的代码:

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

3 个答案:

答案 0 :(得分:2)

要读取堆栈转储,请查看第一行,然后向下阅读:

/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>'

第一行告诉您问题的触发位置和原因:在ActiveModel的attribute_methods方法中,因为在对象中找不到answer的setter。这是通过您migrate.rb脚本第139行的调用触发的。堆栈跟踪的技巧是读取它,查找您编写的脚本。在我们的代码中,问题确实很好,因此从假设我们的错误开始总是好的。

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

是问题所在。您的Question班级没有answer的设定者。您丢失或拼错了attribute_accessor来电或拼错def answer=方法。

要调试我建议使用Ruby Debugger 1.9gem install ruby-debug19。它是1.9.2,易于使用。您可以在代码中设置断点,然后从命令行运行它,该命令行将一直运行,直到达到断点并在调试器中停止。从那里,您可以使用l列出当前行,使用p显示变量的内容,或者如果安装了漂亮的打印机,则执行require 'pp'。您可以使用s单步执行某些方法,也可以使用n逐步执行“下一步”。还有c继续,c 100继续特定的行号;在该示例中为100。您可以使用b 100在第100行设置断点,然后c运行,每次都停在100。 irb会将您带入IRB,并且已经初始化了该点的变量,因此您可以查看它们。还有很多其他命令,但那些是我经常使用的命令。

答案 1 :(得分:0)

这可能意味着您已为问题类定义了答案属性:

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

您还应该学习如何使用rdebug,以便您可以在没有帮助的情况下逐步完成代码并将其弄清楚。

答案 2 :(得分:0)

我认为您的模型问题没有answer属性。 在这个cast中,您可以学习如何调试rails app