Rails recurive view weird behavior with object association

I have a comment table that is linked to itself for answers. Basically, a comment that has parent_id is also a response to its parent comment.

To do this, I use a recursive view, very simple, that worked in the past, but does not work with rails 3.2.0 and ruby ​​2.1.1

Here is the 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 %> 

Exit:

349,223; A comment
Array
349,229; A comment
A comment

In the second iteration, comment.replies is a comment, not an array, and everything falls from there.

But if I change the first line and add a reboot:

 <% x = comment.reload.replies %> 

everything starts to work, output:

349,223; A comment
Array
349,229; A comment
Array
349230; A comment
Array

I would like to understand what is happening here, and how the association can return an instance of one object instead of its list and why it works with reloading.

Model code added:

 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 
+7
ruby ruby-on-rails
source share
1 answer

I think the problem is that when you enter the comment response area, you added ActiveRecord::Association::CollectionProxy as an intermediary between the original comment and the response to the comment. It says:

The @reflection object represents the macro :has_many .

What follows from your use :has_many in model code. In Rails 4, at least CollectionProxy contains a cache in the collection of objects that are linked via :has_many . This example from the documentation describes the caching / reload process.

I quickly searched the cache in the CollectionProxy source for Rails 4 and Rails 3.2 , and it is not mentioned in the Rails 3.2 documentation. But this could be implemented before the documentation was changed.

It may also be ideological, but using #is_a? could have been avoided. You can simply use :respond_to?(:each) so you can use any type of Enumerable .

CHANGE! Check this out from Source CollectionProxy :

 # 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 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 seems that comment.replies is actually just giving you HasManyAssociation , not the actual object. Since CollectionProxy is new in Rails 3.1, this may be your problem.

+1
source share

All Articles