我在sinatra应用程序中遇到了一个非常奇怪的问题。重要的代码部分就是这个:
puts "url: #{url.inspect}"
is_music_post = nil
is_video_post = nil
is_music_post = defined?(url.music_post_id) != nil
is_video_post = defined?(url.video_post_id) != nil
puts "vid post: #{is_video_post}"
puts "music post: #{is_music_post}"
URL对象来自mongo mapper。它们看起来像这样:
obejct 1
#<Url _id: BSON::ObjectId('5345d525dcdda73224000240'), music_post_id: BSON::ObjectId('5345d51fdcdda7322400023d'), nice: "beat-rooftop", post_id: nil>
这里按预期工作:
vid post: false
music post: true
obejct 2
#<Url _id: BSON::ObjectId('5345d2f6dcdda732240001d8'), nice: "my-tale-boney-m-steppenwolf", post_id: nil, video_post_id: BSON::ObjectId('5345d2f6dcdda732240001d7')>
在这里变得奇怪,我期待vid post和false for music post,但我得到:
vid post: true
music post: true
obejct 3
#<Url _id: BSON::ObjectId('5345d525dcdda73224000240'), music_post_id: BSON::ObjectId('5345d51fdcdda7322400023d'), nice: "beat-rooftop", post_id: nil>
她的两个价值都是一样的
vid post: true
music post: true
WFT
所以我的猜测就是某个地方有一种状态。那么我怎么能强迫它每次都重新评估呢?
我的系统
ruby -v ruby 2.0.0p353(2013-11-22修订版43784)[x86_64-linux]
更新
我认为@iain可能是正确的延迟加载解释。如果这是真的,我怎么能在这种情况下禁用它?
答案 0 :(得分:0)
从外观上看,MongoMapper正懒惰地创建属性,defined?
不检查字段的值,但字段是否为已定义,因此您需要找到更好的测试以达到预期目标。 There is a discussion about adding lazy attributes from a while back on the mailing list,虽然我不知道它是否曾经实施过。
你第一次创建一个对象时,它有一个music post
,所以它得到true
但vid post
没有。第二次您没有使用音乐帖子字段,但它是使用最后一个对象创建的,因此您获得了true
true
。由于此原因,对象3也会获得true
true
。
尝试将第二个对象放在第一位。如果true
为vid post
但music post
为假,则您会知道属性的定义方式。