Today I had to get an active_scaffold based admin interface working with a model that was a nested set.
Active Scaffold has a "config.nested.add_link" option, but this obviously didn't work just "out of the box" as a nested set does not have any Active Record associations as such. It has children and parents, but these are not found through "has_many" and "belongs_to".
The solution was actually quite simple. Use the Active Scaffold reverse association method and define the association.
So i thought I would write it up here.
First, you have a page model. A page (like a web page) belongs in a tree. A page has a parent and has many children. I am using this as an interface to a website, the root is the home page, which has many links, all of which are children to the root page. Those children can also have children which are then sub pages to that subject.
So we have a page migration and model that looks basically like this:
Migration:
class CreatePages < ActiveRecord::Migration
def self.up
create_table :pages do |t|
t.column :title, :string
t.column :parent_id, :integer
t.column :rgt, :integer
t.column :lft, :integer
end
end
def self.down
drop_table :pages
end
end
Model:
class Page < ActiveRecord::Base
acts_as_nested_set
end
To add the active scaffold work to this, you have to define a self-refferential association between a Page and it's children. As the child is also a page, you use the foreign_key and class_name options to the belongs to and has many.
So this model code becomes:
class Page < ActiveRecord::Base
acts_as_nested_set
belongs_to :parent,
:foreign_key => :parent_id,
:class_name => "Page"
has_many :children,
:foreign_key => :parent_id,
:class_name => "Page"
end
As we already have a "parent_id" as part of the nested set, we can conveniently use this for the association foreign key.
Then, in the controller we can do:
class PagesController < ApplicationController
active_scaffold :page do |config|
config.columns[:children].association.reverse = :parent
config.nested.add_link("Show Children", [:children])
end
end
end
The first line in the config tells Active Scaffold explicitly what the reverse association is. This is needed as the self referrential nested set doesn't just work straight away as it is a bit of a unique case.
The second line simply provides a link on each record to allow you to show it's children.
I hope that helps someone else. Not hard, but will save you the 15 minutes putting the code together.
blogLater
Mikel |
¿ 6/5/2008 - Thanks Much for a great post