Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jb/638 cache descendants #53

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions vendor/engines/your_platform/app/models/dag_link.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class DagLink < ActiveRecord::Base

after_create :delete_cache
after_save :delete_cache
after_destroy :delete_cache

def delete_cache
ancestor.delete_cache if ancestor.try(:respond_to?, :delete_cache)
Expand Down
1 change: 1 addition & 0 deletions vendor/engines/your_platform/app/models/group.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class Group < ActiveRecord::Base
after_create :import_default_group_structure # from GroupMixins::Import

def delete_cache
Structureable
delete_cache_structureable
delete_cached_leaf_groups
end
Expand Down
3 changes: 2 additions & 1 deletion vendor/engines/your_platform/app/models/page.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class Page < ActiveRecord::Base
belongs_to :author, :class_name => "User", foreign_key: 'author_user_id'

def delete_cache
Structureable
delete_cache_structureable
end

Expand Down Expand Up @@ -39,7 +40,7 @@ def to_param
#
def <<(child)
unless child.in? self.children
if child.in? self.descendants
if child.in? self.descendants(true)
link = DagLink.where(
ancestor_type: 'Page', ancestor_id: self.id,
descendant_type: child.class.name, descendant_id: child.id
Expand Down
17 changes: 17 additions & 0 deletions vendor/engines/your_platform/app/models/structureable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,24 @@ def destroy_links
end

def delete_cache_structureable
delete_cached_descendants
delete_cache_roles
end

def delete_cached_descendants
Rails.cache.delete([self, 'descendants'])
end

def cached_descendants
Rails.cache.fetch([self, 'descendants'], expires_in: 1.week) do
descendants(true)
end
end

def descendants(force_reload = false)
descendant_pages(true) if force_reload && self.respond_to?(:descendant_pages)
descendant_groups(true) if force_reload && self.respond_to?(:descendant_groups)
descendants
end
end
end
2 changes: 1 addition & 1 deletion vendor/engines/your_platform/app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,7 @@ def administrated_objects( role = :admin )
objects = directly_administrated_objects( role )
if objects
objects += objects.collect do |directly_administrated_object|
directly_administrated_object.descendants
directly_administrated_object.cached_descendants
end.flatten
objects
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def navable_is_most_special_category?( navable )

def most_special_category
categories_the_current_navable_falls_in.try(:select) do |navable|
(navable.descendants & categories_the_current_navable_falls_in).empty?
(navable.cached_descendants & categories_the_current_navable_falls_in).empty?
end.try(:first)
end

Expand Down
110 changes: 102 additions & 8 deletions vendor/engines/your_platform/spec/models/structureable_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,120 @@

describe Structureable do

describe ".is_structureable" do
describe '.is_structureable' do

before { @node = create( :page ) }
before { @node = create(:page) }
subject { @node }

it "should provide the has_dag_links functionality" do
subject.should respond_to( :parents, :children, :ancestors, :descendants )
it 'should provide the has_dag_links functionality' do
subject.should respond_to(:parents, :children, :ancestors, :descendants)
end

it "should provide the has_many_flags functionality" do
subject.should respond_to( :flags, :add_flag, :remove_flag )
it 'should provide the has_many_flags functionality' do
subject.should respond_to(:flags, :add_flag, :remove_flag)
end

it "should make sure that when objects are destroyed, also their dag links are destroyed" do
@parent = create( :page )
it 'should make sure that when objects are destroyed, also their dag links are destroyed' do
@parent = create(:page)
@parent.child_pages << @node
@node.destroy
@parent.links_as_parent.count.should == 0
end
end

describe '#descendants' do
before do
@node = create(:page)
end
subject { @node.descendants }
it { should == [] }
describe 'after adding child' do
before do
@child = create(:page)
@node.child_pages << @child
end
it { should include @child }
end
describe 'after adding grandchildren' do
before do
@child = create(:page)
@grandchild = create(:page)
@node.child_pages << @child
@child.child_pages << @grandchild
end
it { should include @grandchild }
end
end

describe '#cached_descendants' do
before do
@node = create(:page)
end
subject { @node.cached_descendants }
it { should == [] }
describe 'after adding child' do
before do
@node.cached_descendants
@child = create(:page)
@node.child_pages << @child
end
it { should include @child }
end
describe 'after adding grandchildren' do
before do
@node.cached_descendants
@child = create(:page)
@grandchild = create(:page)
@node.child_pages << @child
@child.child_pages << @grandchild
end
it { should include @grandchild }
end
describe 'after removing grandchildren' do
before do
@child = create(:page)
@grandchild = create(:page)
@node.child_pages << @child
@child.child_pages << @grandchild
@node.cached_descendants
@grandchild.destroy_dag_links
end
it { should_not include @grandchild }
end
describe 'after multiple adding and removing' do
before do
@p1 = create(:page)
@p2 = create(:page)
@p3 = create(:page)
@p4 = create(:page)
@p5 = create(:page)
@p6 = create(:page)
@p7 = create(:page)
@node.cached_descendants
@node.child_pages << @p1
@p1.child_pages << @p2
@node.cached_descendants
@p2.child_pages << @p4
@node.cached_descendants
@node.child_pages << @p3
@node.cached_descendants
@node.child_pages << @p5
@p5.child_pages << @p6
@node.cached_descendants
@p2.destroy_dag_links
@node.cached_descendants
@p5.child_pages << @p7
@node.cached_descendants
@p6.destroy_dag_links
end
it { should include @p1 }
it { should_not include @p2 }
it { should include @p3 }
it { should_not include @p4 }
it { should include @p5 }
it { should_not include @p6 }
it { should include @p7 }
end
end
end