2011-06-25 15 views
1

我在Rails 3.0.1中使用了Ruby 1.8.7,並且遇到了一個問題,它的根本原因似乎是「Array === object 「操作。在我自己創作的課堂中,我看到了同樣的行爲,並且沒有使用「===」操作符(我認爲在我對Ruby的知識方面存在一些缺陷,它仍然相當有限)。但現在它發生在ActionPack內部,我需要做一些事情。Ruby ===不像左邊參數是類時那樣動作

當FormHelper「fields_for」沒有按照它應該的方式行事時,這會浮出水面。下面的視圖代碼片段( 「<%%>」 去除以提高可讀性):

form_for @coupon do |f| 
    ... 
    f.fields_for @coupon.participants do |cp| 
    ... 
    end 
end 

得到錯誤 「::的ActionView模板::錯誤(未定義的方法`模型名稱」的陣列:類):」 在form_for helper方法中。我確定它正在執行「case」命令的錯誤分支,設置斷點並開始測試。下面是結果:

/Library/Ruby/Gems/1.8/gems/actionpack-3.0.1/lib/action_view/helpers/form_helper.rb:1152 
case record_or_name_or_array 
(rdb:1) pp record_or_name_or_array.instance_of? Array 
true 
(rdb:1) pp Array === record_or_name_or_array 
false 
(rdb:1) pp Array.object_id 
2148267660 
(rdb:1) pp record_or_name_or_array.class.object_id 
2148267660 

這說明相當明確的是,雖然「record_or_name_or_array」絕對是一個數組,「陣列=== record_or_name_or_array」是返回false。

順便說一句,如果你懷疑「@ f.fields_for」是錯誤的語法,我試過它和無「@f」。並得到了同樣的結果。我也重新啓動了RoR和我的機器,結果保持不變。

+0

你的病例陳述的整個代碼是什麼? – Dogbert

+1

你可以在問題中包含你的控制器相關動作的代碼嗎?這可能有幫助。 –

+0

我沒有這樣做,因爲它看起來不相關。我的控制器中的代碼是「@coupon = Coupon.find(params [:id])」。參考是Coupon.first.participants,其中參與者是has_many關聯。我已經檢查了軌道控制檯中的參與者,因此我相當確定該關聯能夠正常工作。使用調試器,我停在發生問題的助手的位置,這就是我得到奇怪的行爲:「CASE record_or_name_or_array WHEN Array」,它依賴於===運算符。 –

回答

2

單個實例試試這個:

@coupon = Coupon.last 
Array === @coupon.participants #=> false 
Array === @coupon.participants.find(:all) #=> true 

協會@coupon.participants不是一個數組,它是一個代理。之所以@coupon.participants.class == Array是真正在的ActiveRecord-3.0.9/lib目錄/ active_record /協會/ association_proxy.rb描述:25

補充:另一個有趣的實驗是@coupon.participants.superclass

+0

我現在看到了。它接受一個數組的事實並不意味着它可以接受一個表達爲僞數組的關聯(例如@ coupon.participants)。如果你想指定一個關聯,你必須**使用「f.fields_for:participants」語法。謝謝。 –

0

從控制檯(rails c)嘗試運行:

@coupon = Coupon.last 
Array == @coupon.participants 

如果調用返回false,這很有可能是您的關聯是不正確的設置(即has_many :participantsbelongs_to :coupon)。

+0

我試過了,它返回true。我一直在看參與者的記錄,所以我相當肯定這些關聯是正確的。任何其他想法? –

0

@coupon.is_a? Array應返回true,@coupon === Array將意味着@coupon是等於Array

+0

請記住,行爲不當的代碼在Rails ActionPack中。所討論的代碼行是一個CASE ... WHEN語句,它顛倒了操作數,因此它正在測試Array === record_or_name_or_array而不是相反(===不可交換)。任何其他想法? –

相關問題