提交 8d3ff3ab 编写于 作者: J Jeremy Kemper

acts_as_nested_set works with single-table inheritance. Closes #6030.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@5889 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
上级 ef4ac31d
*SVN* *SVN*
* acts_as_nested_set works with single-table inheritance. #6030 [Josh Susser]
* PostgreSQL: use a subselect to correctly perform eager finds with :limit and :order. #4668 [eventualbuddha] * PostgreSQL: use a subselect to correctly perform eager finds with :limit and :order. #4668 [eventualbuddha]
* Pass a range in :conditions to use the SQL BETWEEN operator. #6974 [dcmanges] * Pass a range in :conditions to use the SQL BETWEEN operator. #6974 [dcmanges]
......
...@@ -163,9 +163,9 @@ def add_child( child ) ...@@ -163,9 +163,9 @@ def add_child( child )
child[left_col_name] = right_bound child[left_col_name] = right_bound
child[right_col_name] = right_bound + 1 child[right_col_name] = right_bound + 1
self[right_col_name] += 2 self[right_col_name] += 2
self.class.transaction { self.class.base_class.transaction {
self.class.update_all( "#{left_col_name} = (#{left_col_name} + 2)", "#{scope_condition} AND #{left_col_name} >= #{right_bound}" ) self.class.base_class.update_all( "#{left_col_name} = (#{left_col_name} + 2)", "#{scope_condition} AND #{left_col_name} >= #{right_bound}" )
self.class.update_all( "#{right_col_name} = (#{right_col_name} + 2)", "#{scope_condition} AND #{right_col_name} >= #{right_bound}" ) self.class.base_class.update_all( "#{right_col_name} = (#{right_col_name} + 2)", "#{scope_condition} AND #{right_col_name} >= #{right_bound}" )
self.save self.save
child.save child.save
} }
...@@ -180,17 +180,17 @@ def children_count ...@@ -180,17 +180,17 @@ def children_count
# Returns a set of itself and all of its nested children # Returns a set of itself and all of its nested children
def full_set def full_set
self.class.find(:all, :conditions => "#{scope_condition} AND (#{left_col_name} BETWEEN #{self[left_col_name]} and #{self[right_col_name]})" ) self.class.base_class.find(:all, :conditions => "#{scope_condition} AND (#{left_col_name} BETWEEN #{self[left_col_name]} and #{self[right_col_name]})" )
end end
# Returns a set of all of its children and nested children # Returns a set of all of its children and nested children
def all_children def all_children
self.class.find(:all, :conditions => "#{scope_condition} AND (#{left_col_name} > #{self[left_col_name]}) and (#{right_col_name} < #{self[right_col_name]})" ) self.class.base_class.find(:all, :conditions => "#{scope_condition} AND (#{left_col_name} > #{self[left_col_name]}) and (#{right_col_name} < #{self[right_col_name]})" )
end end
# Returns a set of only this entry's immediate children # Returns a set of only this entry's immediate children
def direct_children def direct_children
self.class.find(:all, :conditions => "#{scope_condition} and #{parent_column} = #{self.id}") self.class.base_class.find(:all, :conditions => "#{scope_condition} and #{parent_column} = #{self.id}")
end end
# Prunes a branch off of the tree, shifting all of the elements on the right # Prunes a branch off of the tree, shifting all of the elements on the right
...@@ -199,10 +199,10 @@ def before_destroy ...@@ -199,10 +199,10 @@ def before_destroy
return if self[right_col_name].nil? || self[left_col_name].nil? return if self[right_col_name].nil? || self[left_col_name].nil?
dif = self[right_col_name] - self[left_col_name] + 1 dif = self[right_col_name] - self[left_col_name] + 1
self.class.transaction { self.class.base_class.transaction {
self.class.delete_all( "#{scope_condition} and #{left_col_name} > #{self[left_col_name]} and #{right_col_name} < #{self[right_col_name]}" ) self.class.base_class.delete_all( "#{scope_condition} and #{left_col_name} > #{self[left_col_name]} and #{right_col_name} < #{self[right_col_name]}" )
self.class.update_all( "#{left_col_name} = (#{left_col_name} - #{dif})", "#{scope_condition} AND #{left_col_name} >= #{self[right_col_name]}" ) self.class.base_class.update_all( "#{left_col_name} = (#{left_col_name} - #{dif})", "#{scope_condition} AND #{left_col_name} >= #{self[right_col_name]}" )
self.class.update_all( "#{right_col_name} = (#{right_col_name} - #{dif} )", "#{scope_condition} AND #{right_col_name} >= #{self[right_col_name]}" ) self.class.base_class.update_all( "#{right_col_name} = (#{right_col_name} - #{dif} )", "#{scope_condition} AND #{right_col_name} >= #{self[right_col_name]}" )
} }
end end
end end
......
...@@ -51,3 +51,13 @@ class NestedSetWithSymbolScope < Mixin ...@@ -51,3 +51,13 @@ class NestedSetWithSymbolScope < Mixin
def self.table_name() "mixins" end def self.table_name() "mixins" end
end end
class NestedSetSuperclass < Mixin
acts_as_nested_set :scope => :root
def self.table_name() "mixins" end
end
class NestedSetSubclass < NestedSetSuperclass
end
...@@ -77,6 +77,24 @@ set_<%= counter %>: ...@@ -77,6 +77,24 @@ set_<%= counter %>:
type: NestedSet type: NestedSet
<% end %> <% end %>
# Nested set with STI
<%
[ [3100, 0, 1, 10, "NestedSetSuperclass"],
[3101, 3100, 2, 5, "NestedSetSubclass"],
[3102, 3101, 3, 4, "NestedSetSuperclass"],
[3103, 3100, 6, 9, "NestedSetSuperclass"],
[3104, 3103, 7, 8, "NestedSetSubclass"]
].each do |sti| %>
sti_set_<%= sti[0] %>:
id: <%= sti[0] %>
parent_id: <%= sti[1] %>
lft: <%= sti[2] %>
rgt: <%= sti[3] %>
type: <%= sti[4] %>
root_id: 3100
<% end %>
# Big old set # Big old set
<% <%
[[4001, 0, 1, 20], [[4001, 0, 1, 20],
......
...@@ -178,7 +178,19 @@ def test_common_usage ...@@ -178,7 +178,19 @@ def test_common_usage
mixins(:set_1).add_child mixins(:set_4) mixins(:set_1).add_child mixins(:set_4)
assert_equal( 3, mixins(:set_1).all_children.length ) assert_equal( 3, mixins(:set_1).all_children.length )
end
def test_inheritance
parent = mixins(:sti_set_3100)
child = mixins(:sti_set_3101)
grandchild = mixins(:sti_set_3102)
assert_equal 5, parent.full_set.size
assert_equal 2, child.full_set.size
assert_equal 4, parent.all_children.size
assert_equal 1, child.all_children.size
assert_equal 2, parent.direct_children.size
assert_equal 1, child.direct_children.size
child.destroy
assert_equal 3, parent.full_set.size
end end
end end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册