Skip to content

Dynamic Columns with Ajax Scaffold

I”ve been asked a couple of times how to dynamically setup the columns displayed by the AS plugin dependant on the permissions of the user, so I though a quick post would be a good idea.

Basically its very simple, you simply define a hash of all the columns you potentially wish to display keyed by the column name, so something like:

@@columns_hash[:user] = ScaffoldColumn.new(..)
@@columns_hash[:foo] = ScaffoldColumn.new(:name => 'bar')

Then define a before_filter along the lines of:

before_filter :create_columns, :o nly => ['table', 'update_table']

Finally all you need to do is write the create_columns method to assign the appropriate columns dependant on the user:

def create_columns
  if user.is_administrator
    @@scaffold_columns = [ @@columns_hash[:user], @@columns_hash[:foo] ]
  else
    @@scaffold_columns = [ @@columns_hash[:user] ]
  end
end

A bit contrived but you get the idea.

This method should continue working in the upcoming 4.0 version of the plugin (associations, search, all sorts of loveliness in that…..) however I think it will have been refined a bit to get rid of the class variables. But for now, it should solve the problem.

8 Comments

  1. Jonathan Donaldson wrote:

    Scott,

    First off, thanks for both the nice response, and the plugin…it is making my life much easier.

    Second, once you showed this, I found (at least to me) an easier way to do the column filtering….

    I went ahead and did the usual:
    <pre><code>
    @@scaffold_columns = [
    AjaxScaffold::ScaffoldColumn.new(...),
    AjaxScaffold::ScaffoldColumn.new(...)
    ]
    </code></pre>
    for each of the common columns (ones that each user should see), then I did this in the def create_columns:
    <pre><code>
    def create_columns
    if @user.is_admin?
    @@scaffold_columns.insert(2,AjaxScaffold::ScaffoldColumn.new(…admin only column)
    end
    end
    </code></pre>

    you can use the array insert to put a column before or after any of the ones set previously…(integer after .insert( is the position)

    Thanks again for all the hard work!

    Saturday, October 28, 2006 at 6:11 am | Permalink
  2. Scott Rutherford wrote:

    Hi Jonathon, that looks pretty neat. I suspect there are a few more ways too. All good.

    Cheers
    Scott.

    Saturday, October 28, 2006 at 6:11 am | Permalink
  3. Jonathan Donaldson wrote:

    Hmmm…my thought above works great in development, but once I tried in production mode, it looks like it caches the @@scaffold_columns and goes through create_colums each time, so I end up with lots if repeats of ‘admin’ columns…

    any ideas?

    Saturday, October 28, 2006 at 6:11 am | Permalink
  4. Scott Rutherford wrote:

    Hi Jonathon, ah yes, should of thought of that. I think the hash direction I originally outlined would be your best bet. Then the actual column objects are only instantiated once but you can dynamically assign them on each request. As you completely overriding the @@scaffold_columns array you won’t have this problem.

    Cheers
    Scott.

    Saturday, October 28, 2006 at 6:11 am | Permalink
  5. Jorge L. Cangas wrote:

    Well I’m just starting with ajaxscaffold … My problem is I want show a *few* columns in the grid view and *many* columns in the edit view. I tried the @@scaffold_columns way and I think my problem is related with the previous comments, but I’m also new in Ruby. Can help me, please?

    Saturday, October 28, 2006 at 6:11 am | Permalink
  6. Scott Rutherford wrote:

    Hi Jorge, to do this you will need to use the @scaffold_columns to define the grid view and create a custom _form.rhtml template for the edit view.

    Cheers
    Scott.

    Saturday, October 28, 2006 at 6:11 am | Permalink
  7. Jorge L. Cangas wrote:

    Thanks a lot: just this was my intuitive guess, but I find for some most "generic": I have some internal fields I need in each table. My feeling is Ajax-Scaffold is very good at "entry level" but it goes difficultd in more complex views: A master/detail form fo example. Well maybe I must wait for AS 4.0 :-) . I’m tried also streamlinned framework for the same, but it seems immature for now for my work. Sorry if all these feelings is my low expertise in RoR, I don’t sure but I’m learning hard
    Thansk! (sorry also my limited english)

    Saturday, October 28, 2006 at 6:11 am | Permalink
  8. Jeff Wattenmaker wrote:

    Hi

    I tried implementing this with a controller and table that has:<br>

    :suffix => true<br>

    On my column hash I get an error:

    uninitialized class variable @@columns_hash in TeamController

    I have tried naming the hash both columns_hash and users_columns_hash with the same result.

    this is the code in the controller.

    @@users_columns_hash[:user] = AjaxScaffold::ScaffoldColumn.new(:name => ‘first’, :name => ‘last’)
    @@users_columns_hash[:foo] = AjaxScaffold::ScaffoldColumn.new(:name => ‘email’)

    I have also tried without the AjaxScaffold:: before ScaffoldColumn and same result.

    Assume I am doing something wrong, can you help.

    thanks.

    Jeff

    Saturday, October 28, 2006 at 6:11 am | Permalink