GithubHelp home page GithubHelp logo

awesome_nested_set's People

Contributors

awagener avatar bkeepers avatar bluegod avatar botandrose-machine avatar danielmorrison avatar dosire avatar ericsmith66 avatar ggoodale avatar graygilmore avatar jhawthorn avatar jswanner avatar krzysiek1507 avatar marahin avatar markusq avatar marutosi avatar masayuki avatar mishina2228 avatar nagyt234 avatar oesgalha avatar p8 avatar parndt avatar petergoldstein avatar rathgar avatar semaperepelitsa avatar shekibobo avatar shevaun avatar stuart avatar tiagoefmoraes avatar ugisozols avatar zilkey avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

awesome_nested_set's Issues

move_to_new_parent determines root parent only as nil

Hello!
When you set parent_id = 0 it raises NoRecord error with ID = 0.
imho it would be more logical to define this method like this:

    def move_to_new_parent
      if @move_to_new_parent_id.nil? || @move_to_new_parent_id == 0
        move_to_root
      elsif @move_to_new_parent_id
        move_to_child_of(@move_to_new_parent_id)
      end
    end

It allows to create select field with mandatory selection:

<select name="parent_id">
  <option value="">--select parent--</option>
  <option value="0">none</option>
  <option value="1">parent1</option>
  <option value="2">parent2</option>
</select>

Massively corrupted nested set

Hi there, for some reason some of my customers nested sets have become heavily corrupted. The root node doesn't contain many of the sub-nodes which is causing major havoc. I've just recently converted them from acts_as_tree so I'm not 100% sure when the corruption occurred.

Anyway the damage is done, so I'm just wondering if there are any tools out there that can help fix up problems like this. The only thing I can think of is forcing a rebuild! and ordering by lft just to help maintain the order of objects in the tree. Is there anything else I can do?

Should I upgrade to a later version of awesome nested set? :)

Cheers,

Brendon

Any way of doing move_to_first_child_of

Hello,
I'm using successfully this plug-in.
But I move a node, sometime I'd like it to be the FIRST children of it's new parent, not the last as it appears to be the case for now...
I was considering doing of dirty hack, but I don't really understand the code of move_to, and I'd like not to break my existing code.
So if you see a simple way of doing that, please tell me !
Regards,

self_and_siblings causes wrong # of bind variables error

Problem:
hash format doesn't seem to play well with strings as keys (at least not in combination w/ other scopes)

Fix:
lib/awesome_nested_set.rb:
def self_and_siblings
nested_set_scope.scoped :conditions => {parent_column_name.to_sym => parent_id}
end

Proof:

c = Comment.first; Comment.find :all, :conditions => {c.parent_column_name.to_sym => c.parent_id}
=> [#<Comment id: 1, title: nil, ...
c = Comment.first; Comment.find :all, :conditions => {c.parent_column_name => c.parent_id}
ActiveRecord::PreparedStatementInvalid: wrong number of bind variables (0 for 1) in: comments.parent_id is ?
from vendor/rails/activerecord/lib/active_record/base.rb:2400:in raise_if_bind_arity_mismatch'

Deeply Nested Children

There is a descendants method, however this fetches all descendants into a flat collection. Often times one wants a nested collection of descendants where they can iterate through children and sub-children at each level.

It would be great if there was a method called nested_children or something which would call descendants but then remap the nesting in memory. So calling nested_children on a child would not trigger an SQL call but return the sub-children mapped in memory. One could use recursion to display this. For example:

<ul>
<% for child_node in node.nested_children %>
  <li><%= render child_node %></li>
<% end %>
</ul>

I believe this would also help improve performance on the select helper method since isn't this currently performing a separate SQL query each time the children are fetched?

Level generates a query every time you access record.level

category.level issues a query every time. Isn't it a better option we cache level for each record by adding a field level in a model and calculate at create or move actions only. Or we can calculate level for any category by just adding 1 to the level of its parent object.

Problems running tests

I am trying to run tests for this plugin by "rake test:plugins --trace" from the root of the application. The result I am getting is the following. Any idea to solve this would be greatly appreciated.

C:\Ruby\bin\ruby.exe -e STDOUT.sync=true;STDERR.sync=true;load($0=ARGV.shift) C:\Ruby\bin/rake test:plugins --trace
Testing started at 10:48 ...
(in C:/Users/andreas/RubymineProjects/multiple_nested_set)
** Invoke test:plugins (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute test:plugins
C:/Ruby/bin/ruby.exe -I"lib;test" "C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "vendor/plugins/awesome_nested_set/test/awesome_nested_set/helper_test.rb" "vendor/plugins/awesome_nested_set/test/awesome_nested_set_test.rb"
C:/Ruby/lib/ruby/gems/1.8/gems/activesupport-2.3.4/lib/active_support/dependencies.rb:440:in load_missing_constant': uninitialized constant CollectiveIdea::Acts::NestedSet::TestCaseClass (NameError) from C:/Ruby/lib/ruby/gems/1.8/gems/activesupport-2.3.4/lib/active_support/dependencies.rb:80:inconst_missing'
from ./vendor/plugins/awesome_nested_set/test/awesome_nested_set/helper_test.rb:6
from C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb:5:in load' from C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb:5 from C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb:5:ineach'
from C:/Ruby/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb:5
rake aborted!

Retrieve an entire tree with one AR Call

This is kind of related to issue #12 by ryanb but different enough I think that it deserves its own ticket.

I have a recursive helper which creates a navigation tree using HAML (with links etc.)

def create_category_tree(category)
  haml_tag "ul.navigation" do
    haml_tag :li do
      haml_tag( :a, category.name, {:href => category_path(category)} )
      category.children.each do |child|
        create_category_tree(child)
      end
    end
  end
end

Currently when I use it it makes many SQL Calls for the various children. If I use nested :include in the AR finder I can reduce the number of calls, something like

HAML VIEW
- Category.all(:conditions => {:parent_id => nil}, :include => {:children => {:children => :children}}).each do |category|
  - create_category_tree(category)

However, this of course doesn't scale depending on the number of children and is ugly as sin and a crime against rails etc.

What I am after is a method that retrieves all the current node and all the children in a standard AR structure so that it can be retrieved with a single SQL call and worked on just like a normal set of AR records.

Is it currently possible to do this? I cannot find anything obvious and ryanb's code doesn't quite do what I would like it to from what I can see.

Cheers

RJ

Creating multiple root-nodes with the view-helper

I'm a rails-newbie trying to create multiple root nodes using a_n_s. I wasn't sure whether multiple roots are supported, but methods like "all_roots_valid?()" lead me to suspect so.

When using

<%= f.select :parent_id, nested_set_options(Storage, @storage) {|i| "#{'-' * i.level * 2} #{i.name}" } %>

in my new-view, I can select all existing nodes as parent for my new node. But I just cannot figure out how to create further root-nodes (parent_id=NULL) using this approach, because the generated would have to include a NULL-. How can I do this? Also, I'd prefer to indent children in the selectbox using " " instead of "-", but the html is escaped to "&nbsp;", so that doesn't work. Any ideas how I could get that working? I hope this is the right forum to ask these kinds of questions. thanks! ben

Not woking well when doing something like find_or_create_by_*

When trying:
Page.root.children.find_or_create_by_title('contact')
wiil rails an ActiveRecord::RecordNotFound Exception

the break point is in:

        def move_to(target, position)
          raise ActiveRecord::ActiveRecordError, "You cannot move a new node" if self.new_record?
          return if run_callbacks(:before_move) == false
          transaction do
            if target.is_a? self.class.base_class
              target.reload_nested_set
            elsif position != :root
              # load object if node is not an object
              target = nested_set_scope.find(target)
            end
            self.reload_nested_set

The line:

target = nested_set_scope.find(target)

The find() method will raise an ActiveRecord::RecordNotFound Exception
but if replace find() with find_by_id() method will get another error:
NoMethodError: undefined method `left' for nil:NilClass

How to resolve this issue ?

Using rails 3.0.pre and getting "NoMethodError: undefined method 'callback' ..."

My Organization model acts_as_nested_set:
org1 = Organization.find(1)
org2 = Organization.find(2)
org2.move_to_child_of(org1)

This gives the following error:
NoMethodError: undefined method callback' for #<Organization:0x10323af10> from […]/activemodel/lib/active_model/attribute_methods.rb:240:inmethod_missing'
from […]/activerecord/lib/active_record/attribute_methods.rb:38:in method_missing' from […]/plugins/awesome_nested_set/lib/awesome_nested_set.rb:507:inmove_to'
from […]/plugins/awesome_nested_set/lib/awesome_nested_set.rb:404:in `move_to_child_of'

I wish I knew more about how to fix this, but it seems that Rails 3.0 changed the way it handles callbacks? I am using Edge Rails which I set up with these instructions. Am I missing something, or does anyone have any ideas?

Handling concurrency during move_to operation

Hi,

I understand the logic and mechanics behind nested set, but I have a question regarding concurrency. We've got multiple independent processes creating nodes in the nested set.
I understand during the insertion of new nodes, that the tree to the right of the new node needs to move to the right by having each nodes lft and rgt increased by +2.
Is there any table locking going on in awesome_nested_set, that would safeguard one process' move_to operation from trampling over another's ? I don't see anything in the code that would suggest that.

Kind regards,
Ijonas.

after_create callbacks cannot see ancestors

I've got a simple subject hierarchy, one of my after_create callbacks needs to know the names of all of the ancestors so I can generate a neat name "foo/bar/baz". To do this I was using the self_and_ancestors method. However, on closer inspection this uses a named scope - so will only return values that are already saved in the database, and as each parents left and right columns are updated after the leaf has been saved - it only ever returns it's self.

Now I was thinking of altering the code to detect if it's a new record and fallback to a more recursive method of returning the ancestors but it occurs to me this will cause no end of pain for people who are using self_and_ancestors in a chain of named_scopes.

How would you deal with this?

New children don't show up in their parent's .descendants

I'm having problems where when I move A to be the child of B, A doesn't show up in B.descendants, even though B shows up in A.ancestors.

Is there a reason this shouldn't pass?

def test_assigning_parent_on_create
  category = Category.create!(:name => "Child", :parent => categories(:child_2))
  assert_equal categories(:child_2), category.parent
  assert_equal categories(:child_2).id, category.parent_id
  assert_not_nil category.left
  assert_not_nil category.right
  assert Category.valid?
  assert categories(:child_2).descendants.include? category
end

(taken from awesome_nested_set_test.rb)

counter_cache support

acts_as_tree enable to config counter_cache and I need this feature.
Why not adding :counter_cache to the options and belongs_to :parent config ?

move into different scope?

Hi,

as far as i see, its not possible to move a node into a different tree (scope). Is it? Why not?
For example I have a node with :scope=>nil, :parent=>nil, :lft=>1, :rgt=>2
And another node with :scope=>1,:paranet=>nil, :lft=>1, :rgt=>2
And wanted to move the first one to child of second one.

Thanks and regards, Phil

Rebuild script and legacy position column

Hi there, just thought perhaps there should be consideration in the rebuild! method for a position column. This is nice for people converting from acts as tree with acts as list for positioning. I just hacked the method to sort by position rather than left, right and id. Worked a charm, but perhaps there could be some kind of parameter passed in to override the ordering?

Also found this plugin for those struggling with drag and drop sorting after converting to nested set. I didn't end up using it because it's designed for dragging and dropping between different parents, but I took the basics and applied it to my project. It works well :)

http://github.com/robinsp/sortable_element_for_nested_set/tree/master

Cannot create sub-nodes on Rails 3 Beta

Hello.
I have installed plugin into my rails 3 app.
I can create root nodes but when I am trying to create a sub-node(move_to_child_of or create method's params include parent) i am getting an error below:

NoMethodError: undefined method proxy_options' for #<ActiveRecord::NamedScope::Scope:0x7f083cf81510> from /var/lib/gems/1.8/gems/activerecord-3.0.0.beta/lib/active_record/relation.rb:318:inmethod_missing'
from /var/lib/gems/1.8/gems/activerecord-3.0.0.beta/lib/active_record/named_scope.rb:183:in method_missing' from /var/rails/market/vendor/plugins/awesome_nested_set/lib/awesome_nested_set.rb:567:inmove_to'
from /var/lib/gems/1.8/gems/activerecord-3.0.0.beta/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in transaction' from /var/lib/gems/1.8/gems/activerecord-3.0.0.beta/lib/active_record/transactions.rb:182:intransaction'
from /var/lib/gems/1.8/gems/activerecord-3.0.0.beta/lib/active_record/transactions.rb:188:in transaction' from /var/rails/market/vendor/plugins/awesome_nested_set/lib/awesome_nested_set.rb:509:inmove_to'
from /var/rails/market/vendor/plugins/awesome_nested_set/lib/awesome_nested_set.rb:405:in `move_to_child_of'
from (irb):1

Can we define range based scope

Hi,
I have a requirement to create scope based on two attributes range (using BETWEEN operator). Like table.min_value <= product_id <= table.max_value.
Thank you in advance!

could not find template "html"

I get this error when running doc:plugins:awesome_nested_set, I installed rdoc_html_templates but doesn't do anything:

My gems:
rails (2.3.5)
rake (0.8.7)
rdoc (2.4.3)
rdoc_html_templates (2.3.0)

Thanks for your help !

cocozz@kakawette ~/dev/enruscats/trunk/ $ rake doc:plugins --trace
(in /home/cocozz/dev/enruscats/trunk)
** Invoke doc:plugins (first_time)
** Invoke doc:plugins:awesome_nested_set (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute doc:plugins:awesome_nested_set
rdoc -o doc/plugins/awesome_nested_set --title 'Awesome Nested Set Plugin Documentation' --line-numbers --inline-source --charset utf-8 -T html vendor/plugins/awesome_nested_set/lib/awesome_nested_set.rb vendor/plugins/awesome_nested_set/lib/awesome_nested_set/helper.rb
--inline-source will be removed from RDoc on or after August 2009
Parsing sources with 2 thread(s)...
100% [ 2/ 2] vendor/plugins/awesome_nested_set/lib/awesome_nested_set/helper.rb

Generating Darkfish...
uh-oh! RDoc had a problem:
could not find template "html"

run with --debug for full backtrace
rake aborted!
Command failed with status (1): [rdoc -o doc/plugins/awesome_nested_set --t...]
/home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:995:in sh' /home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:1010:incall'
/home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:1010:in sh' /home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:1094:insh'
/home/cocozz/dev/enruscats/trunk/vendor/rails/railties/lib/tasks/documentation.rake:84
/home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:636:in call' /home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:636:inexecute'
/home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:631:in each' /home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:631:inexecute'
/home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:597:in invoke_with_call_chain' /usr/lib/ruby/1.8/monitor.rb:242:insynchronize'
/home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:590:in invoke_with_call_chain' /home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:607:ininvoke_prerequisites'
/home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:604:in each' /home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:604:ininvoke_prerequisites'
/home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:596:in invoke_with_call_chain' /usr/lib/ruby/1.8/monitor.rb:242:insynchronize'
/home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:590:in invoke_with_call_chain' /home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:583:ininvoke'
/home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:2051:in invoke_task' /home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:2029:intop_level'
/home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:2029:in each' /home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:2029:intop_level'
/home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:2068:in standard_exception_handling' /home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:2023:intop_level'
/home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:2001:in run' /home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:2068:instandard_exception_handling'
/home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake.rb:1998:in run' /home/cocozz/.gem/ruby/1.8/gems/rake-0.8.7/bin/rake:31 /usr/bin/rake:19:inload'
/usr/bin/rake:19

Nested set node move breaks after_save chain

Hey dude,

We've been using your plugin recently and while it is super cool and has sped things up considerably, we encountered a couple of nasty bugs on the creation of our hierarchical objects.

Specifically, lines 516 and 570 of awesome_nested_set.rb in #move_to cause an ActiveRecord reload which in turn halts the after_save filter chain.

We haven't been able to come up with a proper solution, so the workarounds we've implemented involve a) always invoking acts_as_nested_set after any other chains and b) always saving the newly created object before assigning any has_many association objects (this seems to be because usage of the << operator on has_many associations of unsaved new objects causes an after_save to be set up to subsequently create the join table entries).

Not sure what you can do, but thought I should bring it to your attention.

Regards,
Elliot Crosby-McCullough
Eden Development

update_attributes should fail when move_to_child_of fails

I am in the process of converting from betternestedset to awesome_nested_set and am having to create wrappers around methods (specifically move_to_child_of) because update_attributes is proceeding to save the record when move_to_child_of fails.

I have created a wrapper around move_to_child_of to perform validations necessary to determine if the move is legal, and if not returning false. With betternestedset, when the move_to_child_of would return false it would return false to update_attributes to I could raise an error to the user about the change. I am having to write a bunch of extra code ensure that it doesn't allow the saving of a record.

Can you tell me if this is something that is fixable?

Thanks

Brad

Creating the root node and a child at the same time

I've run into some bother when trying to 'seed' my CMS with a root folder and a page within that folder. Basically the seeding happens when the application finds its database empty, so only on a new instance of the CMS. What is happening is The folder gets created with left and right of 1, 2, then even though the page is created with the parent being the folder, the left and right of the page is 3, 4.

I've tested just seeding the database with a folder, then making a page within it using the application (like a normal user would) and it all works well. The process I'm using to seed the page is the same as a user would, just that it happens in the same process call, rather than being executed in a separate request to the server.

I'm presuming there's some kind of refresh that needs to take place so that awesome_nested_set will place the page within the folder properly?

Undefined Method Error

I have just installed awesome_nested_set, and I am getting the following error when I try to use the move_to_child_of method on an object whose model is configured with acts_as_nested_set:
NoMethodError (undefined method `move_to_child_of')

What could be causing this? I am using Rails 2.3.8 and ruby 1.8.7 (2010-06-23 patchlevel 299) [i386-mingw32].

move_to transaction reload problems

def move_to wraps its db update in a transacion, which is quite ok. But when creating a new record for an object which also saves with a transaction(with optimistic locking via col =>lock_version) AR chockes when reloading the current object in line 570 because the record is not saved yet.

I guess reloading is done so other callbacks can see the update, i just commented out the line which works for me.
(.. AR callbacks, locking and transactions shot me in the foot a couple of times)

Declare either attr_protected or attr_accessible for Category, but not both.

I've set up a basic Category model, with a schema table that looks like this:

create_table "categories", :force => true do |t|
    t.integer  "parent_id"
    t.string   "name"
    t.text     "description"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "lft"
    t.integer  "rgt"
 end

In my Category model, I have the following line:

attr_accessible :name, :description, :parent_id

I've implemented a form partial to edit or add a new category, using the example code in the readme to create a select:

<%= f.select :parent_id, nested_set_options(Category, @category) {|i| "#{'-' * i.level} #{i.name}" } %>

When I submit the new category form, the following error occurs:

RuntimeError in CategoriesController#create

Declare either attr_protected or attr_accessible for Category, but not both.

Any help would be appreciated.

before_destory filter (destroy_descendants) is executed to fast

it is executed before class before_destory callbacks witch makes problem -

before filter checks if there is any articles in descendants

def check_if_category_or_descendants_have_any_articles
  KnowledgeBase::Article.in_category(self).count == 0
end

but before it is executed all descendants are delete from db and i don't know how to solve this

Second issue is connect with updating of lft and rgt even when deleting leaf

 KnowledgeBase::Category Delete all (0.3ms)   DELETE FROM "knowledge_base_categories" WHERE ("lft" > 2 AND "rgt" < 3)                         
  KnowledgeBase::Category Update (0.3ms)   UPDATE "knowledge_base_categories" SET "lft" = ("lft" - 2) WHERE ("lft" > 3)                        
  KnowledgeBase::Category Update (0.4ms)   UPDATE "knowledge_base_categories" SET "rgt" = ("rgt" - 2) WHERE ("rgt" > 3)                        
  SQL (1.0ms)   SELECT count(*) AS count_all FROM "knowledge_base_articles" WHERE (category_id IN (SELECT id FROM knowledge_base_categories WHERE lft >= 2 AND rgt <= 3))

sollution for leaf problem is straight forward

    # back to the left so the counts still work.
    def destroy_descendants
      return if leaf? || right.nil? || left.nil? || skip_before_destroy

but i don't know how to solve problem with triggering callback (destroy_descendants)
meybe it should be executed after node is destroyed

Moving elements

Hello, If I create a new object, it has a lft value of nil. If I try to move that object, I get
NoMethodError: You have a nil object when you didn't expect it!
The error occurred while evaluating nil.<=

which is returned by !((left <= target.left && right >= target.left) or (left <= target.right && right >= target.right)) # (line 410 of awesome_nested_set.rb)

I don't know if a new record should have a default value for lft and rgt. Any idea?

Rails 3 beta deprication warning

I installed the plugin, ran the migration and added it to a model. Runnning 'rake' raised the following warnings:

DEPRECATION WARNING: Base.named_scope has been deprecated, please use Base.scope instead. (called from acts_as_nested_set at /rails/vendor/plugins/awesome_nested_set/lib/awesome_nested_set.rb:89)

DEPRECATION WARNING: Base.named_scope has been deprecated, please use Base.scope instead. (called from acts_as_nested_set at /rails/vendor/plugins/awesome_nested_set/lib/awesome_nested_set.rb:90)

Get an error parent_id_changed? when using rebuild!

I have a class:
class Node < ActiveRecord::Base
acts_as_nested_set :parent_column => "parent_node_uuid"
end

When I verify Node.acts_as_nested_set_options[:parent_column], it outputs my custom column already. But I use Node.rebuild!, I get an error NoMethodError: undefined method `parent_id_changed?'

Sometimes need way of setting parent_id directly

Not so much an issue as a feature request. (Sorry if misfiled. Couldn't see a Lighthouse link or similar.)

It would be great if we had the option of setting parent_id directly sometimes, rather than always using move_to_child_of.

For example, I use seed_fu (http://github.com/mbleigh/seed-fu/tree/master) to seed my development database, and seed_fu can only assign values to instance variables -- it can't call methods from plugins. I'd like to be able to do something like this in seed_fu:

Thing.seed do |s|
  s.id = "2"
  s.parent_id = "1"
end

Comparing two nested_sets

Hi, I hope this is the good place to ask this,

I have two tables in my db, one with MAIN categories, and another for the categories that each of my customers grab for it's businness.

categories

id
name
parent_id
lft
rgt

customers_categories

id
name
parent_id
rgt
lft
customer_id

Ok, that said, I have a view with the typical two multiselect list's, one next to the other, with two buttons between them to "switch" categories, so the customer can grab any categories he wants from the main list.

I already wrote the code to grab categories and save them in 'customer_categories', after that I refresh my two select lists via ajax, so I get my Customercategories.all(:conditions => ['box_id = ?'], params[:customer_id]) to refresh the second list, but the problem comes when I have to refresh my first list, which would be this (in a veeeeeery simplificated way):

@first_list = Categories.all - Customercategories.all(:conditions => ['box_id = ?'])

I am hanging around this trying to write an algorithm to do it but it doesn't seem very easy, since I have to take in consideration ancestors/descendents etc...

Maybe you can show me the path to go ?
Thanks a lot,
cocozz

Use a has_many association for :children

Hi there, just wondering if you could explain why the children method isn't a traditional has_many relationship? I had an issue where I wanted to find a polymorphicly related set of records through the children of a parent run by awesome_nested_set but had to mock up another model to do this because :children isn't a reflection.

See this post: http://stackoverflow.com/questions/1080942/recreating-this-custom-query-using-hasmany/1082977#1082977

I'm sure there's probably a very good reason, I'm just interested to find out :)

Proper indexing for a nested set?

I'm curious what a proper index would be for lft and rgt. For parent_id it's pretty obvious. This website (http://threebit.net/tutorials/nestedset/tutorial1.html) seems to indicate that they should be unique indexes. Do you agree?

Column | Type | Notes
---------+--------+-----------
nid | bigint | Primary Key
parentId | bigint | Foreign Key (nestedSet.nid)
rft | bigint | Unique Key
lft | bigint | Unique Key

Calling #parent on namespaced model causes ArgumentError

Given an awesome_nested_set model that's inside a module, trying to fetch the parent of a record raises "ArgumentError: is not missing constant !" For example, with the following model:

class Namespace::NestedFoo < ActiveRecord::Base
  acts_as_nested_set
end

the following triggers the bug:

    >> root = Namespace::NestedFoo.create
    => #<Namespace::NestedFoo id: 3, parent_id: nil, lft: 1, rgt: 2, created_at: "2009-10-07 03:10:30", updated_at: "2009-10-07 03:10:30">
    >> child = Namespace::NestedFoo.create
    => #<Namespace::NestedFoo id: 4, parent_id: nil, lft: 3, rgt: 4, created_at: "2009-10-07 03:10:40", updated_at: "2009-10-07 03:10:40">
    >> child.move_to_child_of root
    => []
    >> child.parent
    ArgumentError: Namespace is not missing constant NestedFoo!
      from /Library/Ruby/Gems/1.8/gems/activesupport-2.3.4/lib/active_support/dependencies.rb:417:in `load_missing_constant'
      from /Library/Ruby/Gems/1.8/gems/activesupport-2.3.4/lib/active_support/dependencies.rb:80:in `const_missing'
      from /Library/Ruby/Gems/1.8/gems/activesupport-2.3.4/lib/active_support/dependencies.rb:98:in `send'
      from /Library/Ruby/Gems/1.8/gems/activesupport-2.3.4/lib/active_support/dependencies.rb:98:in `const_missing'
      from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb:2197:in `compute_type'
      from /Library/Ruby/Gems/1.8/gems/activesupport-2.3.4/lib/active_support/core_ext/kernel/reporting.rb:11:in `silence_warnings'
      from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.4/lib/active_record/base.rb:2195:in `compute_type'
      from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.4/lib/active_record/reflection.rb:156:in `send'
      from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.4/lib/active_record/reflection.rb:156:in `klass'
      from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.4/lib/active_record/associations/belongs_to_association.rb:49:in `find_target'
      from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.4/lib/active_record/associations/association_proxy.rb:240:in `load_target'
      from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.4/lib/active_record/associations/association_proxy.rb:112:in `reload'
      from /Library/Ruby/Gems/1.8/gems/activerecord-2.3.4/lib/active_record/associations.rb:1247:in `parent'
      from (irb):4

I've forked-and-fixed here: http://github.com/krbullock/awesome_nested_set

Remove view helper or allow parent_id be assigned

Currently, a helper exists to generate a dropdown of categories. However, explicitly assigning parent_id raises an ActiveRecord::ActiveRecordError, so you'd have to do something like:

class Admin::CategoriesController < Admin::BaseController
  before_filter :remove_parent_id, :only => [:create, :update]

  resource_controller

  create.after { @category.move_to_child_of(@parent_id) unless @parent_id.blank? }
  update.after { @category.move_to_child_of(@parent_id) unless @parent_id.blank? }

  private

  def remove_parent_id
    @parent_id = params[:category].delete(:parent_id)
  end
end

I think that either assigning to parent_id should be allowed or the helper get removed so as to not confuse developers.

sorting?

AwesomeModel.all(:order => foo) works but AwesomeModel.roots(:order => foo) doesn't.

??

Reduce cascading left/right recalculations by observing an offset

When working with a massive nested set and relocating a node, it is possible that this will cause a cascade of left/right recalculations affecting tons of other records. Moving a single node should have a minimal impact on other nodes. From my limited observation this results because the left/right assignments across the nesting are sequential and without a gap. By providing an offset, this allows us to avoid a cascading recalculation of nesting in many cases. (This is similar to old-time programming where programmers hand-entered line numbers in increments of 10 in case new lines had to be added in the future.) In this way, only when gaps are filled and a collision occurs, would an across-the-board recalculation be necessary.

Incompatibility with :attr_accessible

As per this post we're by default setting attr_accessible to nil on all our models by using the following in an initializer:

ActiveRecord::Base.send(:attr_accessible, nil) 

and then explicitly specifying which fields should be open to mass-assignment in the individual models.

awesome_nested_set uses attr_protected to protect the left/right columns which I assume to be the source of the RuntimeError: Declare either attr_protected or attr_accessible for Comment, but not both. error that we're geting in our functional tests.

This little hack to /lib/awesome_nested_set.rb seems to resolve this issue:

# no bulk assignment
[left_column_name.intern, right_column_name.intern].each do |protected_attr|
  attr_protected protected_attr if self.attr_accessible.include?(protected_attr)
end

How to Avoid NoMethodError in Testing

I'm posting this solution in case anyone else encounters this problem when using this great plugin.

I test using FactoryGirl and Shoulda. When I first started writing my tests, I was getting NoMethodErrors on some of the test methods provided by AwesomeNestedSet. As part of the philosophy of FactoryGirl, I was avoiding setting the lft and rgt values in my Factories as that lead to highly defined code that could easily become brittle in robust testing.

The answer to the problem lies in the very helpful rebuild! method. After creating models in the Factory, rebuild! the nested set and all of the methods magically become available. This dynamically created the boundary values appropriate to whatever you have designed in your testing code.

# Media Types Factories
Factory.define :media_type do |f|  
  f.name 'media type'   
end

Factory.define :media_type_child, :class => MediaType do |f|  
  f.name 'child media type'   
end
# Testing code Excerpt
context "when there is a parent" do
  setup do 
    @parent = Factory.create(:media_type)
    MediaType.rebuild!
    post :create, :media_type => Factory.attributes_for(:media_type_child), :parent => @parent.id
  end

  # Working Test
  should "be a child type" do
    assert assigns(:media_type).child?
  end

  # Working Test
  should "be a child of the parent" do
    assert assigns(:media_type).is_descendent_of?(assigns(:parent))
  end
end

awesome_nested_set breaks has_one nested_attributes

I have has_one assiociation with nested_attributes enabled. Before including awesome_nested_set everything works just fine. After adding awesome_nested_set the nested attributes for the has_one assiociation are lost. I "fixed" it in my code to use an has_many.

I have no clue why or how this is happening.

Set child order

Current the order for the children assocation is hard-coded to the left column, being able to change this would be very useful. I am not sure if we would need to replace the default ordering or add to so that we could have something like
has_many :children, :class_name => self.base_class.to_s, :foreign_key => parent_column_name, :order => "#{quoted_left_column_name}, #{an_override}"

basic descendants is broken?

ag.children

=> []

ag2 = AccountGroup.create({:name => 'System Administrators'})

=> #<AccountGroup id: 173, name: "System Administrators", description: nil, parent_id: nil, lft: 345, rgt: 346, slfgrp: nil, created_at: "2010-02-26 08:56:16", updated_at: "2010-02-26 08:56:16">

ag3 = AccountGroup.create({:name => 'Architecture'})

=> #<AccountGroup id: 174, name: "Architecture", description: nil, parent_id: nil, lft: 347, rgt: 348, slfgrp: nil, created_at: "2010-02-26 08:56:23", updated_at: "2010-02-26 08:56:23">

ag2.move_to_child_of ag

=> []

ag3.move_to_child_of ag

=> []

ag.children

=> [#<AccountGroup id: 174, name: "Architecture", description: nil, parent_id: 172, lft: 344, rgt: 345, slfgrp: nil, created_at: "2010-02-26 08:56:23", updated_at: "2010-02-26 08:56:23">, #<AccountGroup id: 173, name: "System Administrators", description: nil, parent_id: 172, lft: 346, rgt: 347, slfgrp: nil, created_at: "2010-02-26 08:56:16", updated_at: "2010-02-26 08:56:16">]

ag.children.size

=> 2

ag4 = AccountGroup.create({:name => 'Platform Services'})

=> #<AccountGroup id: 175, name: "Platform Services", description: nil, parent_id: nil, lft: 349, rgt: 350, slfgrp: nil, created_at: "2010-02-26 08:58:03", updated_at: "2010-02-26 08:58:03">

ag4.move_to_child_of ag2

=> []

ag.children.size

=> 2

ag.descendants.size

=> 2

** Shouldn't descendants be equal to 3? FTR, when I uninstall awesome_nested_set and install better_nested_set, without changing any of the above records in the DB, 'ag.all_children' returns 3. 'all_children' is the same method as 'descendants' , which I'm sure you already know.

Moving does not trigger validation

Given a model as such:

class Category < ActiveRecord::Base
  validates_presence_of :name
  validates_uniqueness_of :name, :scope => :parent_id
  acts_as_nested_set
end

And this should then pass:

@root = Factory(:category, :name => "one")
@sub = Factory(:category, :name => "two")
@sub.move_to_child_of(@root)
@sub.update_attribute(:name, "one")
@sub.move_to_root
assert_equal @root.id, @sub.parent_id

I'm assuming that @sub.move_to_root wouldn't succeed since it would update the record into an invalid state. If that sounds unreasonable, please let me know.

sortable_element support

Hello,

I'm using AwesomeNestedSet to replace acts_as_list and acts_as_tree and i'm very satisfied.

And now, i'm trying to make a interface to reorder tree using sortable_element provided by Rails but I dont know how I can reorder records using the received params by Script.aculo.us.

I tryed this plugin http://github.com/robinsp/sortable_element_for_nested_set without success also.

I don't know if this is a feature request or a possible "plugin" of AwesomeNestedSet. You can talk about this feature?

Best regards

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.