To be used with acts_as_ordered_tree
Ruby
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
lib
tasks
test
.gitignore
MIT-LICENSE
README.textile
Rakefile
init.rb
install.rb
uninstall.rb

README.textile

ActsAsContainable

Created for use with ordered_tree where you may need to put different models as elements in that tree. This is the coded solution given here.

Installation

ruby script/plugin install http://github.com/ramontayag/acts_as_containable

If you want to have more explicit rules as to what can be a parent of what, then

create_table “containers”, :force => true do |t| t.string “containable_type”, :null => false t.integer “containable_id”, :null => false t.datetime “created_at” t.datetime “updated_at” t.integer “parent_id”, :default => 0, :null => false t.integer “position” end
  1. Make a migration file with this in it (sorry, lazy to make migration generators):
    
    class CreateContainer < ActiveRecord::Migration
      def self.up
        create_table "containers", :force => true do |t|
          t.string   "containable_type",                :null => false
          t.integer  "containable_id",                  :null => false
          t.datetime "created_at"
          t.datetime "updated_at"
          t.integer  "parent_id",        :default => 0, :null => false
          t.integer  "position"
        end
      end
def self.down drop_table “containers” end

end

  1. copy vendor/plugins/acts_as_containable/lib/container.rb to your own app/models
  2. Add your own custom rules. For example, I added the method:

  # it would be nice to eventually move this config to the ActiveRecord model that
  # acts_as_containable. Maybe something like this
  # acts_as_containable :only => [:page, :album]
  # acts_as_containable :except => [:page]
  # acts_as_containable :except => :all # Can't parent anything; leaf node.
  # It may default to allow all
  def can_parent?(record)
    rules = {
      :image => [],
      :attachment => [],
      :page => [:page, :album, :image, :attachment, :font],
      :album => [:image, :album],
      :font => []
    }

    if record.is_a?(Symbol)
      class_name = record
    else # It must be a record
      class_name = record.class.name.underscore.to_sym
    end

    if rules.empty?
      true
    else
      rules[containable_type.underscore.to_sym].\
        include?(class_name)
    end
  end

Usage

Model

class MyModel < AR::Base
acts_as_containable
end

Controller

class MyModelsController < ApplicationController
acts_as_containable

#Have all actions except destroy and create, unless you want to override them
end

View
Easiest way is to add a parent_id hidden_field_tag to your model/new form – the controller will take care of the rest.


	hidden_field_tag :parent_id, params[:parent_id]

This means, if I want the image I’m about to create to be a child of album, then make the link:


new_image_path(:parent_id => @album.container.id)

TODO

  • There are no tests, except on my application that uses this plugin, therefore there should be tests built into this, or at least a testing application that is uploaded with this plugin as a submodule.

Copyright © 2010 Ramon Tayag, released under the MIT license