为什么要定义?一个状态

时间:2014-05-17 11:26:25

标签: ruby sinatra mongomapper

我在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可能是正确的延迟加载解释。如果这是真的,我怎么能在这种情况下禁用它?

1 个答案:

答案 0 :(得分:0)

从外观上看,MongoMapper正懒惰地创建属性,defined?不检查字段的,但字段是否为已定义,因此您需要找到更好的测试以达到预期目标。 There is a discussion about adding lazy attributes from a while back on the mailing list,虽然我不知道它是否曾经实施过。

你第一次创建一个对象时,它有一个music post,所以它得到truevid post没有。第二次您没有使用音乐帖子字段,但它是使用最后一个对象创建的,因此您获得了true true。由于此原因,对象3也会获得true true

尝试将第二个对象放在第一位。如果truevid postmusic post为假,则您会知道属性的定义方式。