Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

remove page class from the allowed children of the parent, and restor…

…e it after destroy
  • Loading branch information...
commit 36a7f8791d8be1dd7de96d9e1fb303112aa03a33 1 parent 452b0b8
@saturnflyer saturnflyer authored
View
12 app/models/archive_page.rb
@@ -1,17 +1,17 @@
class ArchivePage < Page
- cattr_accessor :allowed_children
cattr_accessor :single_use_children
@@single_use_children = [ArchiveDayIndexPage, ArchiveMonthIndexPage, ArchiveYearIndexPage, FileNotFoundPage]
- @@allowed_children = [self.default_child, *@@single_use_children]
- def allowed_children
- overlap = @@allowed_children & (existing_child_types - [default_child])
+ def set_allowed_children_cache
+ singles = self.class.single_use_children.map(&:name)
+ existing = existing_child_types.map(&:name)
+ all = allowed_children_lookup.map(&:name)
- (@@allowed_children - overlap)
+ self.allowed_children_cache = (all - (singles & existing)).join(',')
end
def existing_child_types
- children(:select => 'DISTINCT class_name, title, virtual', :order => nil).collect{|p| p.class }.uniq
+ children(:select => 'DISTINCT class_name, title, virtual', :order => nil).map(&:class_name).compact.map(&:constantize).uniq
end
description %{
View
7 archive_extension.rb
@@ -9,11 +9,10 @@ class ArchiveExtension < Radiant::Extension
def activate
# allow bootstrap
if Page.table_exists?
+ ArchiveMenuRenderer # Initialize the class because it is lazily loaded
+ MenuRenderer.exclude 'ArchiveDayIndexPage', 'ArchiveMonthIndexPage', 'ArchiveYearIndexPage'
Page.class_eval do
- def allowed_children_with_archive
- allowed_children_without_archive.reject { |p| p.name =~ /Archive(Day|Month|Year)IndexPage/ }
- end
- alias_method_chain :allowed_children, :archive
+ include PageChildrenCacheUpdates
end
end
end
View
41 lib/page_children_cache_updates.rb
@@ -0,0 +1,41 @@
+module PageChildrenCacheUpdates
+ def self.included(base)
+ base.class_eval do
+ after_create :remove_from_parent_allowed_children_cache
+ after_destroy :add_to_parent_allowed_children_cache
+ end
+ end
+
+ private
+
+ def remove_from_parent_allowed_children_cache
+ if parent_allows_this_child_class? && class_is_single_use_for_parent?
+ parent.allowed_children_cache = parent_allowed_class_names.delete_if{|child| child == page_class_name }.join(',')
+ parent.save
+ end
+ end
+
+ def add_to_parent_allowed_children_cache
+ if class_is_single_use_for_parent? && !parent_allows_this_child_class?
+ parent.allowed_children_cache = (parent_allowed_class_names + [page_class_name]).uniq.join(',')
+ parent.save
+ true
+ end
+ end
+
+ def parent_allows_this_child_class?
+ parent? && parent.allowed_children_cache.to_s.split(',').include?(page_class_name)
+ end
+
+ def class_is_single_use_for_parent?
+ parent? && parent.class.respond_to?(:single_use_children) && parent.class.single_use_children.map(&:name).include?(page_class_name)
+ end
+
+ def parent_allowed_class_names
+ parent.allowed_children_cache.to_s.split(',')
+ end
+
+ def page_class_name
+ self.class_name.present? ? self.class_name : 'Page'
+ end
+end
View
14 spec/models/archive_page_spec.rb
@@ -34,23 +34,11 @@
end
its(:single_use_children){ should == [ArchiveDayIndexPage, ArchiveMonthIndexPage, ArchiveYearIndexPage, FileNotFoundPage]}
- its(:allowed_children){ should == [Page, *ArchivePage.single_use_children]}
describe '#existing_child_types' do
it 'should return a unique array of classes of the page children' do
- archive.existing_child_types.should == archive.children.all(:select => 'DISTINCT class_name, title, virtual').collect{|p| p.class }.uniq
+ archive.existing_child_types.should == archive.children(:select => 'DISTINCT class_name, title, virtual', :order => nil).map(&:class_name).compact.map(&:constantize).uniq
end
end
- describe '#allowed_children' do
- context 'when no children exist' do
- subject{ ArchivePage.new }
- its(:allowed_children){ should == ArchivePage.allowed_children }
- end
- it 'should remove any existing single_use_children from the allowed_children' do
- existing_except_default = archive.existing_child_types - [archive.default_child]
- used_allowed_children = ArchivePage.allowed_children & existing_except_default
- archive.allowed_children.should == (ArchivePage.allowed_children - used_allowed_children)
- end
- end
end
View
25 spec/models/page_spec.rb
@@ -1,6 +1,27 @@
require File.expand_path("../../spec_helper", __FILE__)
describe Page do
- its(:default_child){ should == Page}
- its(:allowed_children){ should == [Page, *Page.descendants.sort_by(&:name)].select(&:in_menu?).reject{|p| p.name =~ /Archive(Day|Month|Year)IndexPage/}}
+ context 'when the parent page has single_use_children' do
+ it 'should remove its class from the parent page allowed_children_cache after create' do
+ ArchivePage.stub!(:single_use_children).and_return([ArchiveDayIndexPage])
+ parent = ArchivePage.create!(:slug => 'archive', :title => 'archive',
+ :breadcrumb => 'archive',
+ :allowed_children_cache => 'Page,ArchiveDayIndexPage')
+ page = ArchiveDayIndexPage.new(:slug => 'day', :title => 'day', :breadcrumb => 'day')
+ page.parent = parent
+ page.save!
+ parent.allowed_children_cache.should_not include('ArchiveDayIndexPage')
+ end
+ it 'should add its class to the parent page allowed_children_cache after destroy' do
+ ArchivePage.stub!(:single_use_children).and_return([ArchiveDayIndexPage])
+ parent = ArchivePage.create!(:slug => 'archive', :title => 'archive',
+ :breadcrumb => 'archive',
+ :allowed_children_cache => 'Page,ArchiveDayIndexPage')
+ page = ArchiveDayIndexPage.new(:slug => 'day', :title => 'day', :breadcrumb => 'day')
+ page.parent = parent
+ page.save!
+ page.destroy
+ parent.allowed_children_cache.should include('ArchiveDayIndexPage')
+ end
+ end
end
Please sign in to comment.
Something went wrong with that request. Please try again.