我正在从数据库迁移数据并收到我无法理解的错误。我是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
答案 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.9。 gem 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