Man my app is causing me so much grief lately. Okay let''s say I have: class Discussion has_many :posts end class Post belongs_to :discussion acts_as_tree end Then let''s say I grab a discussion object and try to eager load all of its posts: discussion = Discussion.find(:first, :include => [:posts]) Seems simple enough and it grabs an entire tree of posts. However: discussion.posts.first.children will run a MySQL query instead of (more smartly) simply accessing the already eager-loaded posts. I''m getting pretty aggravated. I''ve been trying to properly handle going about my app for ages and nothing seems to work optimally. Any ideas? More importantly: should I even bother. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Eleo wrote:> discussion = Discussion.find(:first, :include => [:posts]) > > Seems simple enough and it grabs an entire tree of posts. However: > > discussion.posts.first.children > > will run a MySQL query instead of (more smartly) simply accessing the > already eager-loaded posts.To avoid a query you have to eager load all the levels you''ll be accessing: discussion = Discussion.find(:first, :include => {:posts => :children}) -- We develop, watch us RoR, in numbers too big to ignore. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
That doesn''t make any sense to me though. When I do Dicussion.find(:first, :include => [:posts]) I have effectively grabbed all the posts, including the children and those children and so on. All of the posts, including children, have the same discussion_id, after all. Another problem with :include => {:posts => :children} is that it only grabs one level of children. I can make the include argument more complex but there''s no way to know how deep a tree is. I''ve found a better way to get children without queries is something like: discussion.posts.collect {|post| if post.parent_id = num}.compact Which will grab the children of a certain parent. This of course only works if I indeed have an entire tree of posts pre-loaded. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Eleo wrote:> That doesn''t make any sense to me though. When I do > Dicussion.find(:first, :include => [:posts]) I have effectively grabbed > all the posts, including the children and those children and so on. All > of the posts, including children, have the same discussion_id, after > all. > > Another problem with :include => {:posts => :children} is that it only > grabs one level of children. I can make the include argument more > complex but there''s no way to know how deep a tree is. > > I''ve found a better way to get children without queries is something > like: > > discussion.posts.collect {|post| if post.parent_id = num}.compact > > Which will grab the children of a certain parent. This of course only > works if I indeed have an entire tree of posts pre-loaded.OK, I didn''t realise discussion.posts contained every post in the discussion, rather than just the top-level posts. Perhaps you should use Better Nested Set: http://opensource.symetrie.com/trac/better_nested_set/ This will allow you to fetch the posts in depth-first order, so you can render whole discussion trees without searching, sorting, or re-querying. -- We develop, watch us RoR, in numbers too big to ignore. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
I am using better nested set right now, but I don''t see precisely how I''m supposed to render without searching/sorting/querying. As it is, foo.children or the like will still query the database. Can you elaborate on how this is supposed to work, please? -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Eleo wrote:> I am using better nested set right now, but I don''t see precisely how > I''m supposed to render without searching/sorting/querying. As it is, > foo.children or the like will still query the database. Can you > elaborate on how this is supposed to work, please?Fetch all posts using discussion.posts.find(:all, :order => ''lft''), then write a recursive rendering function that loops through these, watching for the parent_id to change, increasing the depth by one when it changes to the id of the previous object, otherwise popping back up the levels until the parent_ids match. -- We develop, watch us RoR, in numbers too big to ignore. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
That makes sense (I think). Thanks. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
This is the best I could come up with def show_thread(posts, parent_id = nil) #result = '''' result = "<ul>\n" posts.each do |post| if post.parent_id == parent_id result += "<li>\n" result += render(:partial => ''post'', :object => post) + "\n" result += show_thread(posts, post.id) unless posts.select {|p| p.parent_id == post.id }.empty? result += "</li>\n" end end result += ''</ul>'' end It''s a massive waste of CPU ticks since it iterates through the array once for every item in the array and uses Array#select each time, but everything else I tried wasn''t working. The larger the thread, the dumber this method gets. If anyone has anything better please let me know. I tried something along the lines of what you suggested. While I figured out how to determine if the depth changed I ultimately couldn''t figure out how to close off all the tags properly. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---