#262 Trees with Ancestry
Apr 18, 2011 | 9 minutes |
The Ancestry gem works like a tree but also allows us to fetch deeply nested messages in a single query. It provides a method to arrange them after fetching.
- Download:
- source code
- mp4
- m4v
- webm
- ogv
I thought this was not covered, What would happen to the child messages when the parent message is deleted ?
Would this be controlled by the plugin that is being used to show ancestry list ?
if the messages contain javascript, would that get executed now that we're using html_safe in the nested_messages helper?
Perhaps in an advanced sequel to this, you can cover one of the jQuery plug-ins to create a file manager style functionality. I have one open source implementation which is non-ajax here:
http://www.github.com/bruparel/file_manager
Thanks for this episode, I will be sure to look into this.
Is that comparable with awesome_nested_set?
Thanks for this episode, Ryan. I`m about to build shopping cart, just for testing. For managing the categories i`ll use ancestry, but i have one question for you guys. How can i use different view for each level of the tree?
*>Is that comparable with awesome_nested_set?*
awesome_nested_set has been superseded by
a fork which has been renamed to just "nested_set" https://github.com/skyeagle/nested_set
Thanks, Ryan! I just finished building this identical functionality into one of my projects. Unfortunately, I'm still a beginner so I had to go the elementary route (essentially looping thru each parent comment and for each of them, looping thru the child comment). It works very nicely but I think I like your way of doing it better!
@Sairam, Ancestry has an ":orphan_strategy" option you can pass to determine how to handle the child records when the parent is deleted. Check out the readme for details.
@Aditya Them message content is already escaped when the message partial is rendered, so marking it as html_safe is fine here.
@Skully, yes, I did take a look at awesome_nested_set and the nested_set fork, but I liked Ancestry a bit more.
@jui, You can call the "depth" method on the model to determine the level and change the rendering accordingly. Alternatively if you can do this with CSS, change the styles depending on the ".nested_messages" depth.
Hey Ryan, just wondering why you use a `for message in @messages` loop in the messages index.html.erb rather than `@messages.each do |message|` block. Personal preference?
I'm with Ryan on this one. Even though for..in is "unfashionable," it's more expressive and easier to type. That's a good combination.
The only reason I've heard for why people don't use it is because (other) people don't use it.
You really do have a uncanny way of covering the right topic just when someone needs it. I was wondering how to go about threaded comments areas, and frankly, not impressed with awesome_nested_set (and looked dated). Was going to just go ahead with a regular comments area for my project's launch, but Ancestry looks perfect and I think I will go ahead with threading. Thanks again.
How do you make a "select" input for let's say categories? They have an example https://github.com/stefankroes/ancestry/wiki/Creating-a-selectbox-for-a-form-using-ancestry ... but it doesn't really work as I did expect. It includes the current category you are editing... which is not cool. :-(
I ran into the same issue, I resolved it by adding an ignore parameter on the tree method.
I have a Family model (for a product):
In my view partial, I use the following to render a select tag - obviously the id_to_ignore is the family_id of the family I want to exclude in my select tag:
I hope this helps.
Anybody who have suckerfish example from the ancestry`s wiki, working?
@Alexander Try deleting the current category yourself in the controller.
Ancestry uses the Materialized Path (MP) technique for encoding nested trees. It differs from Nested Set (NS) encoding in that with nested sets, each insert/update/delete updates close to half of the records in the tree. With MP, only the manipulated node and its descendants are modified.
This page [https://communities.bmc.com/communities/docs/DOC-9902] is a pretty good analysis of the three well-known nested tree encodings. Also, the book SQL for Smarties by Joe Celko treats this topic very nicely.
Thanks for this Railscast, I'll be needing nested tress very soon, and was not relishing writing my own implementation of MP.
This lib is amazing, thanks for this screencast. Note that #arrange method does not work perfectly if you have a too recent activerecord and an order clause in your default_scope's model. See the issue on github if needed ( https://github.com/stefankroes/ancestry/issues/42 ).
Cool gem and great cast. It would be also nice if ancestry provided with ~ #leaves method - set of children that have no children ... - quite useful in some situations ;)
Thanks ryan,
I just start working on a project that require some categorization. Should see this rails cast last night. The subtree and arrange are what exactly I'm looking for.
I should use this insted of nested_set
Hi,
I am going to implememnt this one for showing menus & sub menus,
but the problem is how to sort this one according user wish, like act_as_list it uses position to sort the list, is there any way I can sort the tress?
In nested_set it uses lft & rgt column, to sort entire tree..
Is there any equivalent functionality available?
Please let me know.
Thanks,
Pradeep CS
hi ryan i use rails 3.0.0 and the @message.parent in new.html.erb does not display the parent attribute
I have the same problem with Rails 3.1.3
fixed it by using
@message = Message.new
@message.parent_id=params[:parent_id]
instead of
@message = Message.new(:parent_id => params[:parent_id])
Thanks so much! This was a lifesaver.
Hi ryan the arrange method is not working for ruby 1.8.7.
Did anyone find a workaround for the arrange method in Ruby 1.8.7?
I am trying to enhance a few features within a two year old Rails application. Would greatly appreciate any ideas.
Just a note... if you use this in combination with RailsCasts #154 to give ancestry to comments, make sure you ignore parent_id in the method find_commentable or you'll encounter the error 'uninitialized constant Parent'. Oops!
What about pagination? is the library compatible with it? I wouldn't like to get 900 nested comments in one single call.
Thanks Ryan.
But how to mix this RailsCast with the #196 (http://railscasts.com/episodes/196-nested-model-form-part-1) ?
I've tried "accepts_nested_attributes_for :children", any ideas to do this?
Thanks a lot ^^
I am trying this example on Rails 3.1 and i get an error
< %= render @message.parent if @message.parent % >
Missing partial messages/message with {:handlers=>[:erb, :builder, :coffee], :formats=>[:html], :locale=>[:en, :en]}. Searched in:
Can someone help?
Do you have a _message.html.erb partial in your app/views/messages directory?
Rails 3.2, getting an odd error where it closes the div class nested-messages then prints the content, then echoes the div again, like this (i'm using folders instead of messages)
Hi Ryan, would you have some nice solutions to tackle the #82 issue of ancestry? (Problem with the to_json of the arrange method)
I keep getting an error saying
undefined method `new_message_path'
This is in app/views/messages/_messages.html.erb
for
<%= link_to "Reply", new_message_path(:parent_id => message) %>
<% if current_user?(message.user) %>
<%= link_to "delete", message, method: :delete,
confirm: "You sure?",
title: message.content %>
<% end %>
Any idea where to define new_message_path? I tried adding
def new_message_path
end
in app/controllers/message/controllers
but it didnt work
nvm I fixed it by adding resources:messages to my routes.rb file
I am building this functionality into my projects.
I would like to have the order of all the parent messages from new to old and the order of child messages from old to new.
Here is my code
<%= nested_microposts @microposts.arrange(:order => :created_at) %>
the code in model/message.rb seems to override .arrange(:order => :created_at)
So the order of all the messages is from new to old and the nested function doesn't work.
Can I arrange the order of all the messages as what I say??
Did anyone ever figure out how to do this?
And another gem, closure_tree: https://github.com/mceachen/closure_tree
"Closure Tree is a mostly-API-compatible replacement for the ancestry, acts_as_tree and awesome_nested_set gems".
A couple of things I found:
subtree.arrange
scope does not work if you have a default scope on your model, you also cannot use the inlineunscoped
method to undo the default scope, as this also undoes the 'subtree' scope. You have to useThe recursive function given in the cast does not correctly handle the situation where you have siblings in the subtree. In this case it incorrectly emits empty
<div>
sections.You must add
attr_accessible :parent_id
or some other accommodation so that adding new sub-messages does not produce a mass-assignment exception.I have a problem i have got the ancestry working but i cannot get the nested_messages helper to work as i keep getting the following error
undefined method `map' for #ActiveSupport::SafeBuffer:0x37c4c28
NoMethodError in Emails#index
6:
7: <%= button_to 'New Email', new_email_path, method: 'get', :class => "btnNew1" %>
8:
9: <%= nested_emails render @emails %>
10:
11:
12:
Hi guys,
My "message" is a nested resource and when trying to implement the nesting for message I am getting the following error. Any clues?
Missing partial messages/message with {:locale=>[:en], :formats=>[:html], :handlers=>[:erb, :builder, :coffee]}. Searched in:
* "C:/Sites/final/cloud/app/views"
Thank you Ryan for the example. I am trying to apply for nested Post-comments-reply but I am stacked. Is there any one who can help me. thanks
Here i found so relevant stuff which i need to know more. thanks a lot for this marvelous article.
j
trending news in the world gives you all the information you need about packers and movers.
Are you planning to shift from one place to another?
then no need to worry at all as to help you out here is the best service of hyderabad, <
local packers and movers in hyderabad
Also if your android device is not performing well then there might be lots of junk in it.
Clear all the junk using falcon mobi cleaner
Hi, nice article. I have been pondering concerning this matter, so thanks for sharing.