Dynamic Columns with Ajax Scaffold
October 28th, 2006
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, :only => ['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.
November 25th, 2007 at 11:18 PM 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: for each of the common columns (ones that each user should see), then I did this in the def create_columns: 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!
November 25th, 2007 at 11:18 PM Hi Jonathon, that looks pretty neat. I suspect there are a few more ways too. All good. Cheers Scott.
November 25th, 2007 at 11:18 PM 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?
November 25th, 2007 at 11:18 PM 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.
November 25th, 2007 at 11:18 PM 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?
November 25th, 2007 at 11:18 PM 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.
November 25th, 2007 at 11:18 PM 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)
November 25th, 2007 at 11:18 PM Hi I tried implementing this with a controller and table that has:
:suffix => true
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