当左侧参数是一个类时,Ruby === 不按它的方式行事
我正在使用 Ruby 1.8.7 和 Rails 3.0.1,并且遇到一个问题,其根本原因似乎是“Array === object”操作。我之前在自己创建的类中看到了相同的行为,并通过不使用“===”运算符来围绕它进行编程(我认为我对 Ruby 的了解存在一些缺陷,这仍然相当有限)。但现在它发生在 ActionPack 内部,我需要对此采取一些措施。
当 FormHelper“fields_for”未按其应有的方式运行时,就会出现这种情况。以下视图代码片段(“<% %>”已删除以提高可读性):
form_for @coupon do |f|
...
f.fields_for @coupon.participants do |cp|
...
end
end
给出错误“ActionView::Template::Error(Array:Class 的未定义方法‘model_name’):” 在 form_for 辅助方法内。我确定它正在执行“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 和我的机器,结果保持不变。
I'm using Ruby 1.8.7 with Rails 3.0.1 and am having a problem whose root cause appears to be the "Array === object" operation. I saw the same behavior before in a class of my own creation, and programmed around it by not using the "===" operator (I assumed that there was some flaw in my knowledge of Ruby, which is still rather limited). But now that it is happening inside ActionPack, I need to do something about it.
This surfaced when the FormHelper "fields_for" was not acting the way it should. The following view code snippet ("<% %>" removed to improve readability):
form_for @coupon do |f|
...
f.fields_for @coupon.participants do |cp|
...
end
end
gave the error "ActionView::Template::Error (undefined method `model_name' for Array:Class):"
inside the form_for helper method. I determined that it was executing the wrong branch of a "case" command, set a breakpoint and started testing. Here are the results:
/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
This shows pretty definitively that, while "record_or_name_or_array" is definitely an array, "Array === record_or_name_or_array" is returning false.
BTW, in case you're suspecting that "@f.fields_for" is the wrong syntax, I tried it both with and without the "@f." and got the same result. I have also restarted RoR and my machine and the results remain unchanged.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
从控制台 (
rails c
) 尝试运行:如果该调用返回 false,则很可能您的关联设置不正确(即
has_many :participants
和belongs_to :优惠券
)。From the console (
rails c
) try running:If that call returns false, it is most likely that your associations are incorrectly setup (i.e.
has_many :participants
andbelongs_to :coupon
).@coupon.is_a? Array
应该返回 true,@coupon === Array
意味着@coupon
等于Array
的单例实例@coupon.is_a? Array
should return true,@coupon === Array
would mean@coupon
was equal to the singleton instance ofArray
试试这个:
关联
@coupon.participants
不是一个数组,它是一个代理。 activerecord-3.0.9/lib/active_record/associations/association_proxy.rb:25 中描述了@coupon.participants.class == Array
为 true 的原因添加:另一个有趣的实验是@coupon.participants.superclass。
Try this:
Association
@coupon.participants
is not an array, it is a proxy. The reason why@coupon.participants.class == Array
is true is described in activerecord-3.0.9/lib/active_record/associations/association_proxy.rb:25Added: Another interesting experiment would be
@coupon.participants.superclass
.