Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ tmp/
.rvmrc
*.lock
tmp/
.ruby-version
.ruby-*
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ rvm:
gemfile:
- gemfiles/activerecord_4.1.gemfile
- gemfiles/activerecord_4.2.gemfile
- gemfiles/activerecord_5.0.rc1.gemfile
- gemfiles/activerecord_edge.gemfile

env:
Expand Down
8 changes: 8 additions & 0 deletions Appraisals
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,19 @@ end

appraise 'activerecord-4.2' do
gem 'activerecord', '~> 4.2.0'

platforms :ruby, :rbx do
gem 'mysql2', '~> 0.3.20'
end
end

appraise 'activerecord-5.0.rc1' do
gem 'activerecord', '~> 5.0.0.rc1'
gem 'actionpack', '~> 5.0.0.rc1'
gem 'railties', '~> 5.0.0.rc1'
gem 'rspec-rails', '>= 3.5.0.beta4'
end

appraise 'activerecord-edge' do
gem 'activerecord', github: 'rails/rails'
gem 'arel', github: 'rails/arel'
Expand Down
22 changes: 22 additions & 0 deletions gemfiles/activerecord_5.0.rc1.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# This file was generated by Appraisal

source "https://rubygems.org"

gem "activerecord", "~> 5.0.0.rc1"
gem "actionpack", "~> 5.0.0.rc1"
gem "railties", "~> 5.0.0.rc1"
gem "rspec-rails", ">= 3.5.0.beta4"

platforms :ruby, :rbx do
gem "mysql2"
gem "pg"
gem "sqlite3"
end

platforms :jruby do
gem "activerecord-jdbcmysql-adapter"
gem "activerecord-jdbcpostgresql-adapter"
gem "activerecord-jdbcsqlite3-adapter"
end

gemspec :path => "../"
2 changes: 1 addition & 1 deletion lib/closure_tree/hash_tree.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ module ClassMethods
# There is no default depth limit. This might be crazy-big, depending
# on your tree shape. Hash huge trees at your own peril!
def hash_tree(options = {})
_ct.hash_tree(nil, options[:limit_depth])
_ct.hash_tree(_ct.default_tree_scope(all, options[:limit_depth]))
end
end
end
Expand Down
10 changes: 3 additions & 7 deletions lib/closure_tree/hash_tree_support.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module ClosureTree
module HashTreeSupport
def default_tree_scope(limit_depth = nil)
def default_tree_scope(scope, limit_depth = nil)
# Deepest generation, within limit, for each descendant
# NOTE: Postgres requires HAVING clauses to always contains aggregate functions (!!)
having_clause = limit_depth ? "HAVING MAX(generations) <= #{limit_depth - 1}" : ''
Expand All @@ -13,15 +13,11 @@ def default_tree_scope(limit_depth = nil)
) AS generation_depth
ON #{quoted_table_name}.#{model_class.primary_key} = generation_depth.descendant_id
SQL
scope_with_order(model_class.joins(generation_depth), 'generation_depth.depth')
scope_with_order(scope.joins(generation_depth), 'generation_depth.depth')
end

def hash_tree(tree_scope, limit_depth = nil)
limited_scope = if tree_scope
limit_depth ? tree_scope.where("#{quoted_hierarchy_table_name}.generations <= #{limit_depth - 1}") : tree_scope
else
default_tree_scope(limit_depth)
end
limited_scope = limit_depth ? tree_scope.where("#{quoted_hierarchy_table_name}.generations <= #{limit_depth - 1}") : tree_scope
build_hash_tree(limited_scope)
end

Expand Down
35 changes: 31 additions & 4 deletions spec/label_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ def name_and_order(enum)
end

def children_name_and_order
name_and_order(@parent.children(reload = true))
name_and_order(@parent.children.reload)
end

def roots_name_and_order
Expand Down Expand Up @@ -454,7 +454,7 @@ def roots_name_and_order
it 'should retain sort orders of descendants when moving to a new parent' do
expected_order = ('a'..'z').to_a.shuffle
expected_order.map { |ea| first_root.add_child(Label.new(name: ea)) }
actual_order = first_root.children(reload = true).pluck(:name)
actual_order = first_root.children.reload.pluck(:name)
expect(actual_order).to eq(expected_order)
last_root.append_child(first_root)
expect(last_root.self_and_descendants.pluck(:name)).to eq(%w(10 0) + expected_order)
Expand All @@ -465,13 +465,13 @@ def roots_name_and_order
z = first_root.find_or_create_by_path(path)
z_children_names = (100..150).to_a.shuffle.map { |ea| ea.to_s }
z_children_names.reverse.each { |ea| z.prepend_child(Label.new(name: ea)) }
expect(z.children(reload = true).pluck(:name)).to eq(z_children_names)
expect(z.children.reload.pluck(:name)).to eq(z_children_names)
a = first_root.find_by_path(['a'])
# move b up to a's level:
b = a.children.first
a.add_sibling(b)
expect(b.parent).to eq(first_root)
expect(z.children(reload = true).pluck(:name)).to eq(z_children_names)
expect(z.children.reload.pluck(:name)).to eq(z_children_names)
end
end

Expand Down Expand Up @@ -524,4 +524,31 @@ def roots_name_and_order
expect(Label.roots_and_descendants_preordered.collect { |ea| ea.name }).to eq(expected)
end
end unless sqlite? # sqlite doesn't have a power function.

context 'hash_tree' do
before do
@a = EventLabel.create(name: 'a')
@b = DateLabel.create(name: 'b')
@c = DirectoryLabel.create(name: 'c')
(1..3).each { |i| DirectoryLabel.create!(name: "c#{ i }", mother_id: @c.id) }
end
it 'should return tree with correct scope when called on class' do
tree = DirectoryLabel.hash_tree
expect(tree.keys.size).to eq(1)
expect(tree.keys.first).to eq(@c)
expect(tree[@c].keys.size).to eq(3)
end
it 'should return tree with correct scope when called on all' do
tree = DirectoryLabel.all.hash_tree
expect(tree.keys.size).to eq(1)
expect(tree.keys.first).to eq(@c)
expect(tree[@c].keys.size).to eq(3)
end
it 'should return tree with correct scope when called on scope chain' do
tree = Label.where(name: 'b').hash_tree
expect(tree.keys.size).to eq(1)
expect(tree.keys.first).to eq(@b)
expect(tree[@b]).to eq({})
end
end
end
6 changes: 5 additions & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
require 'rspec'
begin
require 'rspec'
rescue LoadError
# explciitly requiring rspec in ActiveRecord 5+ tests throws exception
end
require 'active_record'
require 'database_cleaner'
require 'closure_tree'
Expand Down