I have a table of comments that is associated with itself for replies. Basically, a comment that has a parent_id is also a reply to his parent comment.
To render this, I use a recursive view, very simple that worked in the past, but is not working with rails 3.2.0 and ruby 2.1.1
Here is simplified code:
<% 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 %>
Output is:
349223; Comment
Array
349229; Comment
Comment
At second iteration, comment.replies
is a Comment, not an Array, and all falls down from there.
But, if I change the first line and add a reload:
<% x = comment.reload.replies %>
all starts working, output is:
349223; Comment
Array
349229; Comment
Array
349230; Comment
Array
I would love to understand what is going on here and how can the association to return a single object instance instead of a list of them and why is working with reload.
Added the model code:
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
I think the issue is that when you enter the scope of the comment reply you've added an ActiveRecord::Association::CollectionProxy
as a middleman between the original comment and the comment response. It says,
The
@reflection
object represents a:has_many
macro.
Which would follow from your use of :has_many
in the model code. In Rails 4, at least, the CollectionProxy
contains a cache on a collection of objects that are associated via :has_many
. This example from the documentation outlines that caching / reloading process.
I did a quick search for "cache" on the CollectionProxy
source for both Rails 4 and Rails 3.2, and it isn't mentioned in the Rails 3.2 documentation. But it could have been implemented before the documentation was changed.
Also, maybe this is ideological, but using #is_a?
could be avoided. You could just use :respond_to?(:each)
, so that you can use any sort of Enumerable
in there.
EDIT! Check it out, from the CollectionProxy source:
# 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
It looks like comment.replies
is actually just giving you a HasManyAssociation
, rather than an actual object. Since CollectionProxy
is new in Rails 3.1, that's probably your problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With