putting back acts_as_tree and some methods for pages
Oleg
committed Aug 31, 2010
commit 049b80d739eafbdd6a05d367e5c93d70ce9dd6ef
Showing 5
changed files with
145 additions
and 11 deletions
app/models/cms_page.rb
+23
-4
| @@ | @@ -1,18 +1,27 @@ |
| class CmsPage < ActiveRecord::Base | |
| + | acts_as_tree :counter_cache => :children_count |
| + | |
| # -- Relationships -------------------------------------------------------- | |
| belongs_to :cms_layout | |
| has_many :cms_blocks, :dependent => :destroy | |
| accepts_nested_attributes_for :cms_blocks | |
| + | # -- Callbacks ------------------------------------------------------------ |
| + | before_validation :assign_full_path |
| + | after_save :sync_child_pages |
| + | |
| # -- Validations ---------------------------------------------------------- | |
| validates :label, | |
| - | :presence => true |
| + | :presence => true |
| validates :slug, | |
| - | :presence => true, |
| - | :format => /^\w[a-z0-9_-]*$/i |
| + | :presence => true, |
| + | :format => /^\w[a-z0-9_-]*$/i, |
| + | :unless => lambda{ |p| p == CmsPage.root || CmsPage.count == 0 } |
| validates :cms_layout, | |
| - | :presence => true |
| + | :presence => true |
| + | validates :full_path, |
| + | :uniqueness => true |
| # -- Instance Methods ----------------------------------------------------- | |
| def render_content | |
| @@ | @@ -29,4 +38,14 @@ class CmsPage < ActiveRecord::Base |
| CmsTag.initialize_tags(self) | |
| end | |
| + | protected |
| + | |
| + | def assign_full_path |
| + | self.full_path = (self.ancestors.reverse.collect{ |p| p.slug }.reject{ |p| p.blank? } + [self.slug]).join('/') |
| + | end |
| + | |
| + | def sync_child_pages |
| + | children.each{ |p| p.save! } if full_path_changed? |
| + | end |
| + | |
| end | |
migrate/01_create_cms.rb b/db/migrate/01_create_cms.rb
+6
-2
| @@ | @@ -8,19 +8,22 @@ class CreateCms < ActiveRecord::Migration |
| t.text :content | |
| t.timestamps | |
| end | |
| - | add_index :cms_layouts, :parent_id |
| add_index :cms_layouts, :label | |
| # -- Pages -------------------------------------------------------------- | |
| create_table :cms_pages do |t| | |
| t.integer :cms_layout_id | |
| + | t.integer :parent_id |
| t.string :label | |
| t.string :slug | |
| t.string :full_path | |
| t.text :content | |
| + | t.integer :position, :null => false, :default => 0 |
| + | t.integer :children_count, :null => false, :default => 0 |
| t.timestamps | |
| end | |
| add_index :cms_pages, :full_path | |
| + | add_index :cms_pages, [:parent_id, :position] |
| # -- Page Blocks -------------------------------------------------------- | |
| create_table :cms_blocks do |t| | |
| @@ | @@ -43,7 +46,8 @@ class CreateCms < ActiveRecord::Migration |
| t.timestamps | |
| end | |
| add_index :cms_snippets, :label, :unique => true | |
| - | |
| + | |
| + | # -- Assets ------------------------------------------------------------- |
| create_table :cms_assets do |t| | |
| t.string :cms_page_id | |
| t.string :file_file_name | |
comfortable_mexican_sofa.rb b/lib/comfortable_mexican_sofa.rb
+8
-3
| @@ | @@ -1,6 +1,11 @@ |
| - | require File.expand_path('comfortable_mexican_sofa/cms_form_builder', File.dirname(__FILE__)) |
| - | require File.expand_path('../app/models/cms_block', File.dirname(__FILE__)) |
| - | require File.expand_path('comfortable_mexican_sofa/cms_tag', File.dirname(__FILE__)) |
| + | %w( |
| + | comfortable_mexican_sofa/cms_form_builder |
| + | comfortable_mexican_sofa/cms_acts_as_tree |
| + | ../app/models/cms_block |
| + | comfortable_mexican_sofa/cms_tag |
| + | ).each do |path| |
| + | require File.expand_path(path, File.dirname(__FILE__)) |
| + | end |
| Dir.glob(File.expand_path('comfortable_mexican_sofa/cms_tag/*.rb', File.dirname(__FILE__))).each do |tag_path| | |
| require tag_path | |
comfortable_mexican_sofa/cms_acts_as_tree.rb b/lib/comfortable_mexican_sofa/cms_acts_as_tree.rb
+108
-0
| @@ | @@ -0,0 +1,108 @@ |
| + | module ActiveRecord |
| + | module Acts |
| + | module Tree |
| + | def self.included(base) |
| + | base.extend(ClassMethods) |
| + | end |
| + | |
| + | # Specify this +acts_as+ extension if you want to model a tree structure by providing a parent association and a children |
| + | # association. This requires that you have a foreign key column, which by default is called +parent_id+. |
| + | # |
| + | # class Category < ActiveRecord::Base |
| + | # acts_as_tree :order => "name" |
| + | # end |
| + | # |
| + | # Example: |
| + | # root |
| + | # \_ child1 |
| + | # \_ subchild1 |
| + | # \_ subchild2 |
| + | # |
| + | # root = Category.create("name" => "root") |
| + | # child1 = root.children.create("name" => "child1") |
| + | # subchild1 = child1.children.create("name" => "subchild1") |
| + | # |
| + | # root.parent # => nil |
| + | # child1.parent # => root |
| + | # root.children # => [child1] |
| + | # root.children.first.children.first # => subchild1 |
| + | # |
| + | # In addition to the parent and children associations, the following instance methods are added to the class |
| + | # after calling <tt>acts_as_tree</tt>: |
| + | # * <tt>siblings</tt> - Returns all the children of the parent, excluding the current node (<tt>[subchild2]</tt> when called on <tt>subchild1</tt>) |
| + | # * <tt>self_and_siblings</tt> - Returns all the children of the parent, including the current node (<tt>[subchild1, subchild2]</tt> when called on <tt>subchild1</tt>) |
| + | # * <tt>ancestors</tt> - Returns all the ancestors of the current node (<tt>[child1, root]</tt> when called on <tt>subchild2</tt>) |
| + | # * <tt>root</tt> - Returns the root of the current node (<tt>root</tt> when called on <tt>subchild2</tt>) |
| + | module ClassMethods |
| + | # Configuration options are: |
| + | # |
| + | # * <tt>foreign_key</tt> - specifies the column name to use for tracking of the tree (default: +parent_id+) |
| + | # * <tt>order</tt> - makes it possible to sort the children according to this SQL snippet. |
| + | # * <tt>counter_cache</tt> - keeps a count in a +children_count+ column if set to +true+ (default: +false+). |
| + | def acts_as_tree(options = {}) |
| + | configuration = { :foreign_key => "parent_id", :order => nil, :counter_cache => nil } |
| + | configuration.update(options) if options.is_a?(Hash) |
| + | |
| + | belongs_to :parent, :class_name => name, :foreign_key => configuration[:foreign_key], :counter_cache => configuration[:counter_cache] |
| + | has_many :children, :class_name => name, :foreign_key => configuration[:foreign_key], :order => configuration[:order], :dependent => :destroy |
| + | |
| + | class_eval <<-EOV |
| + | include ActiveRecord::Acts::Tree::InstanceMethods |
| + | |
| + | def self.roots |
| + | find(:all, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}}) |
| + | end |
| + | |
| + | def self.root |
| + | find(:first, :conditions => "#{configuration[:foreign_key]} IS NULL", :order => #{configuration[:order].nil? ? "nil" : %Q{"#{configuration[:order]}"}}) |
| + | end |
| + | EOV |
| + | end |
| + | end |
| + | |
| + | module InstanceMethods |
| + | # Returns list of ancestors, starting from parent until root. |
| + | # |
| + | # subchild1.ancestors # => [child1, root] |
| + | def ancestors |
| + | node, nodes = self, [] |
| + | nodes << node = node.parent while node.parent |
| + | nodes |
| + | end |
| + | |
| + | # Returns all children and children of children |
| + | def descendants |
| + | nodes = [] |
| + | self.children.each do |c| |
| + | nodes << c |
| + | nodes << c.descendants |
| + | end |
| + | nodes.flatten |
| + | end |
| + | |
| + | # Returns the root node of the tree. |
| + | def root |
| + | node = self |
| + | node = node.parent while node.parent |
| + | node |
| + | end |
| + | |
| + | # Returns all siblings of the current node. |
| + | # |
| + | # subchild1.siblings # => [subchild2] |
| + | def siblings |
| + | self_and_siblings - [self] |
| + | end |
| + | |
| + | # Returns all siblings and a reference to the current node. |
| + | # |
| + | # subchild1.self_and_siblings # => [subchild1, subchild2] |
| + | def self_and_siblings |
| + | parent ? parent.children : self.class.roots |
| + | end |
| + | end |
| + | end |
| + | end |
| + | end |
| + | |
| + | ActiveRecord::Base.send :include, ActiveRecord::Acts::Tree |
| \ No newline at end of file | |
comfortable_mexican_sofa/cms_form_builder.rb b/lib/comfortable_mexican_sofa/cms_form_builder.rb
+0
-2
| @@ | @@ -1,5 +1,3 @@ |
| - | require 'action_view/helpers/form_helper' |
| - | |
| class CmsFormBuilder < ActionView::Helpers::FormBuilder | |
| helpers = field_helpers - | |