2014-05-17 129 views
0

我在我的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映射器。他們是這樣的:

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後真假音樂後,但我得到:

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

所以我的猜測是某個地方有某種狀態。那麼我怎麼能強迫它每次重新評估它呢?

我的系統

紅寶石-v紅寶石2.0.0p353(2013年11月22日修訂43784)x86_64的Linux的]

更新

我覺得@iain可能是對的用懶惰的加載解釋。如果這是真的,我該如何禁用這種情況?

+0

你可以打印什麼'defined?(url.music_post_id)'給你,這會給你一個暗示發生了什麼 – bjhaid

+0

當它是真的返回方法和零或什麼都沒有,當它是假的,沒有任何意外 –

+0

如果它是沒有意外的然後我不明白的問題 – bjhaid

回答

0

通過它的外觀,MongoMapper是懶惰和defined?創建屬性不檢查該字段的值是否被定義,所以你需要找到一個更好的測試,以滿足您預期的目標。 There is a discussion about adding lazy attributes from a while back on the mailing list,但我不知道它是否實施過。

第一次創建對象時,它有一個music post,所以它得到一個truevid post沒有。第二次您不使用音樂發佈字段,但它是用最後一個對象創建的,因此您可以獲得truetrue。對象3也會因此得到truetrue

嘗試先放置第二個對象。如果您得到的truevid post,但對於music post爲false,您會知道這是關於屬性定義方式的問題。

+0

我測試你的想法改變對象的順序,你的權利在這種情況下,這是真實的vid後。但我仍不明白這究竟會發生。 –