module ComfortableMexicanSofa::ActsAsTree::ClassMethods

Public Instance Methods

cms_acts_as_tree(options = {}) click to toggle source
# File lib/comfortable_mexican_sofa/extensions/acts_as_tree.rb, line 11
    def cms_acts_as_tree(options = {})
      configuration = {
        foreign_key:    "parent_id",
        order:          nil,
        counter_cache:  nil,
        dependent:      :destroy,
        touch:          false
      }
      configuration.update(options) if options.is_a?(Hash)

      belongs_to :parent,
        optional:       true,
        class_name:     name,
        foreign_key:    configuration[:foreign_key],
        counter_cache:  configuration[:counter_cache],
        touch:          configuration[:touch]

      has_many :children,
        -> { order(configuration[:order]) },
        class_name:   name,
        foreign_key:  configuration[:foreign_key],
        dependent:    configuration[:dependent]

      class_eval <<-RUBY, __FILE__, __LINE__ + 1
        include ComfortableMexicanSofa::ActsAsTree::InstanceMethods

        scope :roots, -> {
          where("#{configuration[:foreign_key]} IS NULL").
          order(#{configuration[:order].nil? ? 'nil' : %("#{configuration[:order]}")})
        }

        def self.root
          roots.first
        end

        validates_each "#{configuration[:foreign_key]}" do |record, attr, value|
          if value
            if record.id == value
              record.errors.add attr, "cannot be it's own id"
            elsif record.descendants.map {|c| c.id}.include?(value)
              record.errors.add attr, "cannot be a descendant's id"
            end
          end
        end
      RUBY
    end