Rails递归查看与对象关联的奇怪行为

时间:2014-05-28 14:58:45

标签: ruby-on-rails ruby ruby-on-rails-3.2 ruby-2.1

我有一个与回复相关的评论表。基本上,具有parent_id的注释也是对其父注释的回复。

为了渲染这个,我使用递归视图,过去非常简单,但是不能使用rails 3.2.0和ruby 2.1.1

以下是简化代码:

<% x = comment.replies %>
<%= comment.id %>; <%= comment.class %><br/>
<%= comment.replies.class %><br><br>
<hr>
<br><br>
<% if x and x.is_a?(Array) %>
  <%= render :partial => "/_redesign/entry/comment", :collection => x, :as => :comment%>
<% end %>

输出是:

  

349223;评论
  阵列
  349229;评论
  评论

在第二次迭代中,comment.replies是一个注释,而不是一个数组,并且都从那里掉落。

但是,如果我更改第一行并添加重新加载:

<% x = comment.reload.replies %>

全部开始工作,输出为:

  

349223;评论
  阵列
  349229;评论
  阵列
  349230;评论
  阵列

我很想了解这里发生了什么以及关联如何返回单个对象实例而不是它们的列表以及为什么要重新加载。

添加了型号代码:

class Comment < Response
  acts_as_deactivatable :dependencies => [:community_news_feed_items]

  has_many :replies, :class_name=>"Comment", :foreign_key=>"referring_c_id", :order=>"date ASC"

  belongs_to :parent_comment, :class_name=>"Comment", :foreign_key=>"referring_c_id"
end

1 个答案:

答案 0 :(得分:1)

我认为问题在于,当您输入评论回复的范围时,您已在原始评论和评论回复之间添加了ActiveRecord::Association::CollectionProxy作为中间人。它说,

  

@reflection对象代表:has_many宏。

您在模型代码中使用:has_many后会有哪些内容。至少在Rails 4中,CollectionProxy包含通过:has_many关联的对象集合上的缓存。文档中的This example概述了缓存/重新加载过程。

我快速搜索了&#34;缓存&#34;在CollectionProxyRails 4#is_a?来源上,Rails 3.2文档中没有提到它。但它可以在文档更改之前实现。

此外,也许这是意识形态的,但可以避免使用:respond_to?(:each)。您可以使用Enumerable,以便在那里使用任何类型的# This class has most of the basic instance methods removed, and delegates # unknown methods to <tt>@target</tt> via <tt>method_missing</tt>. As a # corner case, it even removes the +class+ method and that's why you get # # blog.posts.class # => Array # # though the object behind <tt>blog.posts</tt> is not an Array, but an # ActiveRecord::Associations::HasManyAssociation. # # The <tt>@target</tt> object is not \loaded until needed. For example, # # blog.posts.count

EDIT!请查看Rails 3.2

comment.replies

看起来HasManyAssociation实际上只是给你一个CollectionProxy,而不是一个实际的对象。由于{{1}}是Rails 3.1中的新功能,这可能是您的问题。