1

我正在使用带有 Rails 3.0.1 的 Ruby 1.8.7 并且遇到了一个问题,其根本原因似乎是“Array === object”操作。我之前在自己创建的一个类中看到了相同的行为,并通过不使用“===”运算符对其进行编程(我认为我对 Ruby 的了解存在一些缺陷,这仍然相当有限)。但现在它发生在 ActionPack 内部,我需要对此做点什么。

当 FormHelper“fields_for”没有按照应有的方式行事时,这种情况就会浮出水面。以下视图代码片段(删除“<% %>”以提高可读性):

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

在 form_for 辅助方法中给出了错误“ActionView::Template::Error (undefined method `model_name' for Array:Class):”。我确定它正在执行“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”绝对是一个数组,但“Array === record_or_name_or_array”返回的是 false。

顺便说一句,如果您怀疑“@f.fields_for”是错误的语法,我尝试了使用和不使用“@f”。并得到相同的结果。我还重新启动了 RoR 和我的机器,结果保持不变。

4

3 回答 3

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/associations/association_proxy.rb:25中有描述

补充:另一个有趣的实验是@coupon.participants.superclass

于 2011-06-26T02:40:23.043 回答
0

@coupon.is_a? Array应该返回 true,@coupon === Array这意味着@coupon等于Array

于 2011-06-25T21:57:02.910 回答
0

从控制台 ( rails c) 尝试运行:

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

如果该调用返回 false,则很可能是您的关联设置不正确(即has_many :participantsbelongs_to :coupon)。

于 2011-06-25T21:32:49.293 回答